HttpServletRequestWrapper 使用笔记
产生背景: HttpServletRequest 对参数值的获取实际调的是org.apache.catalina.connector.Request没有提供对应的set方法修改属性所以不能对前端传来的参数进行修改,实际场所像过滤xss攻击,取认证token统一去除token前缀等需要进行请求参数的处理,此时HttpServletRequestWrapper 就应运而生了。
原理: HttpServletRequestWrapper 采用装饰者模式对HttpServletRequest进行包装,我们可以通过继承HttpServletRequestWrapper 类去重写getParameterValues,getParameter等方法,实际还是调用HttpServletRequest的相对应方法,但是可以对方法的结果进行改装。
例子: 给所有方法自动提供token字段参数。
1)新增wrapper类:
public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper { private final Map<String, String[]> parameterMap; /** * @param request */ public MyHttpServletRequestWrapper(HttpServletRequest request) { super(request); parameterMap = new HashMap<>(request.getParameterMap()); } @Override public String[] getParameterValues(String name) { String[] values = parameterMap.get(name); if (values == null) { values = super.getParameterValues(name); } return values; } public void setParameter(String name, String ...value) { parameterMap.put(name, value); } }
2)新增 filter类传递MyHttpServletRequestWrapper
@Slf4j @WebFilter(filterName = "myFilter", urlPatterns = {"/**"}) @Component public class MyFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { log.info("----------MyFilter---------"); MyHttpServletRequestWrapper MyHttpServletRequest = new MyHttpServletRequestWrapper((HttpServletRequest) request); MyHttpServletRequest.setParameter("age", "50"); chain.doFilter(MyHttpServletRequest, response); } }
3)controller
@RestController @RequestMapping("wrapper") @Slf4j public class RequestWrapperController { @RequestMapping("testWrapper") public void testWrapper(Integer age, String token) { log.info("-----------age :{} ,-------------", age); log.info("-----------token :{} ,-------------", token); } }
4)请求样例
4)结果可以看到 age我们没传,但是因为我们在过滤器设值了age的值所以controller打印出了age,此方法也可以去修改原有参数的值。
下一篇:
SpringBoot日志配置文件