内容替换Filter
有时候需要对网站进行控制,防止输出非法内容或者敏感信息。这时我们可以使用filter来进行内容替换,其工作原理为,在Servlet将内容输出到response时,response将内容缓存起来,在Filter中进行替换,然后再输出到客户浏览器。由于默认的response并不能严格的缓存输出内容,因此需要自定义一个具备缓存功能的response。
可以通过扩展javax.servlet.http.HttpServletResponseWrapper类来实现自定义response。该类实现了javax.servlet.http.HttpServletResponse接口的所有方法,根据需要覆盖其中相应的方法即可,代码如下:HttpServletResponseWrapper.java
package com.yzj.response; import java.io.CharArrayWriter; import java.io.PrintWriter; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; public class HttpCharacterResponseWrapper extends HttpServletResponseWrapper { private CharArrayWriter charArrayWriter = new CharArrayWriter(); //字符数组Writer public HttpCharacterResponseWrapper(HttpServletResponse response) { super(response); // TODO Auto-generated constructor stub } public PrintWriter getWriter(){//覆盖父类方法 return new PrintWriter(charArrayWriter); }//返回字符数组Writer,缓存内容 public CharArrayWriter getCharArrayWriter() { return charArrayWriter;//getter方法 } }View Code
该类覆盖了getWriter()方法,当servlet中使用该response对象调用getWriter()方法来输出内容时,内容将会被输出到CharArrayWriter对象中,达到缓存效果。
Filter中需要自定义的response传进servlet中,代码如下:OutputReplaceFilter.java
package com.yzj.filter; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintWriter; import java.util.Properties; 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.http.HttpServletResponse; import com.yzj.response.HttpCharacterResponseWrapper; public class OutputReplaceFilter implements Filter { private Properties pp = new Properties(); //非法词、敏感词,配置在初始化参数中 @Override public void destroy() { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpCharacterResponseWrapper responseWrapper = new HttpCharacterResponseWrapper((HttpServletResponse) response); chain.doFilter(request, responseWrapper); //doFilter,使用自定义response String output = responseWrapper.getCharArrayWriter().toString(); //得到responseWrapper输出内容 for(Object obj:pp.keySet()){ //遍历所有敏感词 String key = (String) obj; output = output.replace(key, pp.getProperty(key));//替换敏感词 } PrintWriter out = response.getWriter(); //通过原来的response的getWriter()方法输出 out.write(output); out.println("<!--Generated at"+new java.util.Date()+"-->"); } @Override public void init(FilterConfig filterConfig) throws ServletException { //初始化时 String file = filterConfig.getInitParameter("file"); //配置文件的位置 String realPath = filterConfig.getServletContext().getRealPath(file); //文件得实际位置 try { pp.load(new FileInputStream(realPath)); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }View Code
本例中,自定义的response只是一个“伪装”的response。Servlet会通过它输出内容到客户端,但是它的内容只是将内容缓存起来了,并没有真正输出到客户端。最终输出到客户端还是通过原来的response完成。
非法词库配置在properties文件中,通过Filter初始化参数传给内容替换Filter。该properties文件内容如下:sensitive.properties
#amend Chna = China www.baidu.com.cn = ww.baidu.com #replace 色情 = ** 情色 = ** 赌博 = **View Code
内容替换Filter的配置文件。web.xml
<filter> <filter-name>OutputReplaceFilter</filter-name> <filter-class> com.yzj.filter.OutputReplaceFilter </filter-class> <init-param> <param-name>file</param-name> <param-value>/WEB-INF/sensitive.properties</param-value> </init-param> </filter> <filter-mapping> <filter-name>OutputReplaceFilter</filter-name> <url-pattern>*.jsp</url-pattern> </filter-mapping>View Code
jsp文件代码如下:replace.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> Chna <br/> <br/> 色情 <br/> 赌博 <br/> 情色 <br/> <br/> www.baidu.com.cn <br/> </body> </html>View Code