【JAVA】要求パラメータをブロックし、要求ヘッダを設定する

5565 ワード

ビジネスでは、リクエストを統一的にブロックし、リクエストパラメータで新しい変数を計算してリクエストヘッダに設定するシーンがあります.
    以下はそれぞれFilterとInterceptorの2つの方式で実現されるが、(Filterを使用する方法を推奨する.Interceptorの方法はPostとGETの方法にのみ有効であり、PUTなどの他の方法はサポートされていないため、主な原因はHttpServertRequestインタフェースの実現クラスが異なり、以下はPOSTとGETの方法のみがサポートされているためである)
シーン:
2種類のユーザがあり、1種類のユーザの要求にはヘッダヘッダヘッダにユーザ名パラメータ(userName)があり、もう1種類のユーザの要求にはヘッダが要求されていないが、要求パラメータrequestParamにはuserIdパラメータがあり、userIdライブラリなどでuserNameを計算することができる.
必要:
私たちは2種類のユーザーを統一して、私たちのcontrollerレイヤに要求するときにヘッダを統一してuserNameを持っています.
詳細:
次の2つの方法でこの要件が実現され、controllerレイヤはuserNameを取得し、requestParamのuserIdから計算されたuserNameを優先的に使用します.
 
1、Filter実現 
package com.paomo.filter;

import org.springframework.context.annotation.Configuration;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.IOException;
import java.util.*;

@Configuration
@WebFilter(value = "/*")
public class ParamFilter implements Filter {

    private static final String USER_PARAM = "userId";
    
    private static final String USER_HEADER = "userName";

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HeaderMapRequestWrapper requestWrapper = new HeaderMapRequestWrapper(req);
        String userId = request.getParameter(USER_PARAM);


        //          userId  userName
        String userName = getUserNameById(userId);

        requestWrapper.addHeader(USER_HEADER, userName);
        chain.doFilter(requestWrapper, response);
    }

    @Override
    public void destroy() {
    }

    public class HeaderMapRequestWrapper extends HttpServletRequestWrapper {

        public HeaderMapRequestWrapper(HttpServletRequest request) {
            super(request);
        }

        private Map headerMap = new HashMap();

        public void addHeader(String name, String value) {
            headerMap.put(name, value);
        }

        @Override
        public String getHeader(String name) {
            String headerValue = super.getHeader(name);
            if (headerMap.containsKey(name)) {
                headerValue = headerMap.get(name);
            }
            return headerValue;
        }

        @Override
        public Enumeration getHeaderNames() {
            List names = Collections.list(super.getHeaderNames());
            for (String name : headerMap.keySet()) {
                names.add(name);
            }
            return Collections.enumeration(names);
        }

        @Override
        public Enumeration getHeaders(String name) {
            List values = Collections.list(super.getHeaders(name));
            if (headerMap.containsKey(name)) {
                values.add(headerMap.get(name));
            }
            return Collections.enumeration(values);
        }
    }

}

2、Interceptor実現
@Component
public class ParamInterceptor extends HandlerInterceptorAdapter {

    private static final Logger logger = LoggerFactory.getLogger(ParamInterceptor.class);

    private static final String USER_PARAM = "userId";

    private static final String USER_HEADER = "userName";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
            String userId = request.getParameter(USER_PARAM);
            if (StringUtils.isNotBlank(userId)) {

                //          userId  userName
                String userName = getUserNameById(userId);

                reflectSetHeader(request, USER_HEADER, userName);
            }
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        super.afterCompletion(request, response, handler, ex);
    }

    private void reflectSetHeader(HttpServletRequest request, String key, String value){
        Class extends HttpServletRequest> requestClass = request.getClass();
        logger.info("request   ={}", requestClass.getName());
        try {
            Field request1 = requestClass.getDeclaredField("request");
            request1.setAccessible(true);
            Object o = request1.get(request);
            Field coyoteRequest = o.getClass().getDeclaredField("coyoteRequest");
            coyoteRequest.setAccessible(true);
            Object o1 = coyoteRequest.get(o);
            Field headers = o1.getClass().getDeclaredField("headers");
            headers.setAccessible(true);
            MimeHeaders o2 = (MimeHeaders)headers.get(o1);
            o2.removeHeader(key);
            o2.addValue(key).setString(value);
        } catch (Exception e) {
            logger.info("reflect set header error {}", e);
        }
    }
}