产生背景:
HttpServletRequest 不能对前端传来的参数进行修改,但实际场所像过滤xss攻击,取认证token统一去除token前缀等需要进行请求参数的处理。
此时HttpServletRequestWrapper 就应运而生了。
原理:
HttpServletRequestWrapper 采用装饰者模式对HttpServletRequest进行包装,我们可以通过继承HttpServletRequestWrapper 类去重写getParameterValues,getParameter等方法,实际还是调用HttpServletRequest的相对应方法,但是可以对方法的结果进行改装。
例子:
给所有方法自动提供token字段参数。
1)新增wrapper类:
public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper
{
public MyHttpServletRequestWrapper(HttpServletRequest request)
{
super(request);
}
@Override
public String[] getParameterValues(String name)
{
if (name.equals("token")){
return new String[]{"dasdasfagasgasgasa--asdas="};
}
String[] parameterValues = super.getParameterValues(name);
return parameterValues;
}
2)新增 filter类传递MyHttpServletRequestWrapper
@Slf4j
public class MyFilter implements Filter
{
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException
{
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
MyHttpServletRequestWrapper xssRequest = new MyHttpServletRequestWrapper((HttpServletRequest) request);
chain.doFilter(xssRequest, response);
}
}
3)新增配置filter配置类注册filter
@Configuration
public class FilterConfig
{
@SuppressWarnings({ "rawtypes", "unchecked" })
@Bean
public FilterRegistrationBean MyFilterRegistration()
{
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setDispatcherTypes(DispatcherType.REQUEST);
registration.setFilter(new MyFilter());
registration.addUrlPatterns("/*");
registration.setName("MyFilter");
registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE);
return registration;
}
}
4)controller
@RestController
@RequestMapping("wrapper")
@Slf4j
public class RequestWrapperController {
@RequestMapping("testWrapper")
public void testWrapper(String name, String token) {
log.info("-----------name :{} ,-------------", name);
log.info("-----------token :{} ,-------------", token);
}
}
5)请求样例:
6)结果
可以看到 token我们没传,但是controller打印出了token,和我们在getParameterValues返回的一样,此方法也可以去修改原有参数的值。



