HttpServletRequestWrapper类的作用
Servlet规范中中引入的filter是非常有用的,因为它引入了一个功能强大的拦截模式。
filter是这样的一种java对象。它可以在request到达servlet之前拦截HttpServletRequest对象,也可以在服务方法转移控制后拦截HttpServletResponse对象。
我们可以使用filter对象完成的任务有:检查用户的输入、以及压缩web内容。
但是,当我们在使用filter的时候却会发现至少有一半的时间我们都想改变HttpServletRequest对象的参数。如:用filter在HttpServletRequest对象到达Servlet之前将用户输入的空格去掉。但是由于java.util.Map包装的HttpServletRequest对象的参数是不可改变的,那要怎么办呢?
幸运的是,尽管我们不能改变对象本身,但是可以通过装饰模式来改变其状态。
因此,想要改变在httpServletRequest中的参数,可以通过httpServletRequest的装饰类HttpServletRequestWrapper来实现,只需要在装饰类中按照需要重写其getParameter(getParameterValues)方法即可。
示例使用 HttpServletRequestWrapper
解决XSS 攻击问题:
(1)继承 HttpServletRequestWrapper
,重写HttpServletRequestWrapper
中的getParameter
方法:
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
private HttpServletRequest request;
public XssHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
this.request=request;
}
@Override
public String getParameter(String name) {
// 获取之前的参数
String value = super.getParameter(name);
String newValue="";
if(StringUtils.isNotEmpty(value)){
newValue = StringEscapeUtils.escapeHtml(value);
}
return newValue;
}
}
(2)实现 Filter 拦截所有请求:
@WebFilter(filterName = "XSSFilter", urlPatterns = "/*")
public class XSSFilter implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// 1. 使用过滤器拦截所有参数
HttpServletRequest req = (HttpServletRequest) servletRequest;
// 2.重新getParameter方法
XssHttpServletRequestWrapper xssHttpServletRequestWrapper = new XssHttpServletRequestWrapper(req);
// 放行程序,继续往下执行
filterChain.doFilter(xssHttpServletRequestWrapper, servletResponse);
}
@Override
public void destroy() {
}
}
(3)注意点 (项目是基于Spring boot的话需要加上@ServletComponentScan不然找不到Filter)