JavaWeb項目中如何擴展一個Request對象——包裝器HttpServletRequestWrapper

一、使用場景

在一個JavaWeb中我們會遇到統一處理出入參或者處理特殊參數的場景,這些場景就需要我們擴展我們的Request對象。所謂的包裝器就是在原來的基礎上包裝一下就是在原來功能上添加一些其他功能。具體使用場景如下:

  1. 處理過濾器中參數統一加解密問題
  2. 需要爲特殊請求擴展參數問題。

二、具體實現

1、首先繼承HttpServletRequestWrapper
public class MyRequestWrapper extends HttpServletRequestWrapper {

    private Map params = new HashMap<>();

    public MyRequestWrapper(HttpServletRequest request, Map newParams) {
        super(request);
        if(request.getParameterMap() != null){
            this.params.putAll(request.getParameterMap());
        }
        if(newParams != null){
            this.params.putAll(newParams);
        }
    }

    //主要覆蓋這個方法來獲取新的參數對象
    @Override
    public Map getParameterMap() {
        return params;
    }

    public Enumeration getParameterNames() {
        Vector l = new Vector(params.keySet());
        return l.elements();
    }


    @Override
    public String[] getParameterValues(String name) {
        Object v = params.get(name);
        if (v == null) {
            return null;
        } else if (v instanceof String[]) {
            return (String[]) v;
        } else if (v instanceof String) {
            return new String[]{(String) v};
        } else {
            return new String[]{v.toString()};
        }
    }

    /**
     * 根據參數的key獲取參數
     * @param name
     * @return
     */
    @Override
    public String getParameter(String name) {
        Object v = params.get(name);
        if (v == null) {
            return null;
        } else if (v instanceof String[]) {
            String[] strArr = (String[]) v;
            if (strArr.length > 0) {
                return strArr[0];
            } else {
                return null;
            }
        } else if (v instanceof String) {
            return (String) v;
        } else {
            return v.toString();
        }
    }
}

2、編寫過濾器代碼
public class MyFilter implements Filter {
    //日誌
    private static final Logger LOGGER = LogManager.getLogger();
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        LOGGER.info("MyFilter過濾器初始化");
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        //獲取HttpServletRequest對象
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        String ipAddr = HttpUtil.getIpAddress(httpServletRequest);
        LOGGER.info("ip地址爲:" + ipAddr);
        Map paramMap = new HashMap<>();
        paramMap.put("ipAddr", ipAddr);
        MyRequestWrapper myRequestWrapper = new MyRequestWrapper(httpServletRequest, paramMap);
        chain.doFilter(myRequestWrapper, response);
    }
    @Override
    public void destroy() {
        LOGGER.info("MyFilter過濾器被銷燬");
    }
}

編寫完過濾器需要在web.xml添加過濾器配置

    <filter>
        <filter-name>MyFilter</filter-name>
        <filter-class>com.leo.filter.MyFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>MyFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
3、編寫測試代碼
    @RequestMapping(value = "/getIpAddr", method = RequestMethod.GET)
    @ResponseBody
    public String getIpAddr(HttpServletRequest request){
        String ipAddr = request.getParameter("ipAddr");
        LOGGER.info("獲取參數:" + ipAddr);
        return ipAddr;
    }

啓動項目,訪問:http://localhost:8080/springmvc/getIpAddr
測試結果
後臺日誌:

2020-06-04 23:53:26.365 INFO  com.leo.util.HttpUtil:25 [http-apr-8080-exec-3] - getIpAddress(HttpServletRequest) - X-Forwarded-For - String ip=null
2020-06-04 23:53:26.368 INFO  com.leo.util.HttpUtil:33 [http-apr-8080-exec-3] - getIpAddress(HttpServletRequest) - Proxy-Client-IP - String ip=null
2020-06-04 23:53:26.369 INFO  com.leo.util.HttpUtil:39 [http-apr-8080-exec-3] - getIpAddress(HttpServletRequest) - WL-Proxy-Client-IP - String ip=null
2020-06-04 23:53:26.370 INFO  com.leo.util.HttpUtil:45 [http-apr-8080-exec-3] - getIpAddress(HttpServletRequest) - HTTP_CLIENT_IP - String ip=null
2020-06-04 23:53:26.371 INFO  com.leo.util.HttpUtil:51 [http-apr-8080-exec-3] - getIpAddress(HttpServletRequest) - HTTP_X_FORWARDED_FOR - String ip=null
2020-06-04 23:53:26.372 INFO  com.leo.util.HttpUtil:57 [http-apr-8080-exec-3] - getIpAddress(HttpServletRequest) - getRemoteAddr - String ip=127.0.0.1
2020-06-04 23:53:26.373 INFO  com.leo.filter.MyFilter:38 [http-apr-8080-exec-3] - ip地址爲:127.0.0.1
2020-06-04 23:53:26.375 INFO  com.leo.interceptor.HandlerInterceptor1:26 [http-apr-8080-exec-3] - HandlerInterceptor1 preHandle
2020-06-04 23:53:26.376 INFO  com.leo.controller.HelloController:129 [http-apr-8080-exec-3] - 獲取參數:127.0.0.1
2020-06-04 23:53:26.380 INFO  com.leo.interceptor.HandlerInterceptor1:34 [http-apr-8080-exec-3] - HandlerInterceptor1 postHandle
2020-06-04 23:53:26.381 INFO  com.leo.interceptor.HandlerInterceptor1:39 [http-apr-8080-exec-3] - HandlerInterceptor1 afterCompletion
2020-06-04 23:53:26.382 INFO  com.leo.interceptor.HandlerInterceptor1:42 [http-apr-8080-exec-3] - HandlerInterceptor1 過濾的接口耗時:6ms

完整代碼請參考:
chapter-6-springmvc-mybatis1(常規整合)
https://gitee.com/leo825/spring-framework-learning-example.git

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章