重构 - 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;
        }
    }
}

上一篇下一篇

猜你喜欢

热点阅读