重构 - Http请求方式重写
2021-08-08 本文已影响0人
ithankzc
背景
后端基于 restful 建议,定义了 patch, put 等请求方法,但是微信小程序,支付宝小程序却没有完全支持此类方法。
解决步骤
通过让客户端在请求头携带 X-HTTP-Method-Override 参数, 后端根据 X-HTTP-Method-Override 的值, 将原本的请求方法更改为 X-HTTP-Method-Override 属性的值,即后端实际接收的请求方法
方法
这里会举例2种语言的实现方式,在 nodejs ,我们叫做中间件, 在 java 里面,叫做过滤器。
nodejs, 基于 koa 框架
export function override_middleware() {
const override = async (ctx, next) => {
let method = ctx.get('x-http-method-override');
if (!method) {
return next();
}
method = method.toUpperCase();
if (!allowedMethods.has(method)) {
return next();
}
ctx.request.method = method;
return next();
};
return override;
}
const app = new Koa();
// for x-http-method-override
app.use(override_middleware);
java, 基于 spring 框架
package cn.codemao.platform.account.config.security;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Locale;
/**
* 用于兼容不支持 patch, delete 的客户端
*
* @author chenxiaochi
*/
@Slf4j
@Service
public class HttpMethodOverrideFilter extends OncePerRequestFilter {
private static final String X_HTTP_METHOD_OVERRIDE_HEADER = "X-HTTP-Method-Override";
@Override
protected void doFilterInternal(HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull FilterChain filterChain)
throws ServletException, IOException {
String headerValue = request.getHeader(X_HTTP_METHOD_OVERRIDE_HEADER);
if (StringUtils.hasLength(headerValue)) {
String method = headerValue.toUpperCase(Locale.ENGLISH);
HttpServletRequest wrapper = new HttpMethodRequestWrapper(request, method);
filterChain.doFilter(wrapper, response);
}
else {
filterChain.doFilter(request, response);
}
}
private static class HttpMethodRequestWrapper extends HttpServletRequestWrapper {
private final String method;
public HttpMethodRequestWrapper(HttpServletRequest request, String method) {
super(request);
this.method = method;
}
@Override
public String getMethod() {
return this.method;
}
}
}