1、首先,需要编写一个响应的封装器ResponseReplaceWrapper,用它来缓存response中的内容,代码如下:
ResponseReplaceWrapper.java
package com.comp.common; import java.io.CharArrayWriter; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; public class ResponseReplaceWrapper extends HttpServletResponseWrapper { private CharArrayWriter charWriter = new CharArrayWriter(); public ResponseReplaceWrapper(HttpServletResponse response) { super(response); } @Override public PrintWriter getWriter() throws IOException {
//return super.getWriter(); return new PrintWriter(charWriter); } public CharArrayWriter getCharWriter() { return charWriter; } }
2、编写内容过滤器ReplaceFilter,代码如下:
package com.html.common; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletResponse; @WebFilter("/*") public class ReplaceFilter implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletResponse res = (HttpServletResponse)response; ResponseReplaceWrapper resp = new ResponseReplaceWrapper(res); chain.doFilter(request, resp); String outString = resp.getCharWriter().toString(); outString = outString.replace("过滤内容", "***"); PrintWriter out = res.getWriter(); out.write(outString); } @Override public void init(FilterConfig arg0) throws ServletException { } @Override public void destroy() { } }
通过以上步骤,就可以实现过滤非法字符了
ResponseReplaceWrapper.java类里面声明的变量charWriter,一直不得其解,到底是在哪里赋的值。经过调试,发现是在ReplaceFilter类里面chain.doFilter(request, resp);调用完后,charWriter就有值了,我猜大概是这个方法里面有什么操作,把response里的内容赋给了charWriter。
ResponseReplaceWrapper.java类里面复写getWriter()方法,如果返回super.getWriter(),在执行chain.doFilter(request, resp);方法后,页面就有内容输出,但是会导致charWriter没有值;如果返回new PrintWriter(charWriter),在执行chain.doFilter(request, resp);方法后,页面没有内容输出,但是charWriter就有值了,然后拿到charWriter的值,就可以修改这个值,并把修改后的值手工输出到页面上。
我的理解就是,把要输出的内容临时保存起来,进行修改,然后把修改后的内容手工输出。
没有看这个源代码,感觉理解的还是有点一知半解,等我看完源代码,有了更深入的理解,再做补充吧。