一、使用場景
在一個JavaWeb中我們會遇到統一處理出入參或者處理特殊參數的場景,這些場景就需要我們擴展我們的Request對象。所謂的包裝器就是在原來的基礎上包裝一下就是在原來功能上添加一些其他功能。具體使用場景如下:
- 處理過濾器中參數統一加解密問題
- 需要爲特殊請求擴展參數問題。
二、具體實現
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