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;}@Overridepublic 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{@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic 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);}@Overridepublic void destroy() {}}
(3)注意点 (项目是基于Spring boot的话需要加上@ServletComponentScan不然找不到Filter)
