有時候需要對網站進行控制,防止輸出非法內容或者敏感信息。這時我們可以使用filter來進行內容替換,其工作原理為,在Servlet將內容輸出到response時,response將內容緩存起來,在Filter中進行替換,然後再輸出到客戶浏覽器。由於默認的response並不能嚴格的緩存輸出內容,因此需要自定義一個具備緩存功能的response。
可以通過擴展javax.servlet.http.HttpServletResponseWrapper類來實現自定義response。該類實現了javax.servlet.http.HttpServletResponse接口的所有方法,根據需要覆蓋其中相應的方法即可,代碼如下:HttpServletResponseWrapper.java
1 package com.yzj.response; 2 3 import java.io.CharArrayWriter; 4 import java.io.PrintWriter; 5 6 import javax.servlet.http.HttpServletResponse; 7 import javax.servlet.http.HttpServletResponseWrapper; 8 9 public class HttpCharacterResponseWrapper extends 10 HttpServletResponseWrapper { 11 private CharArrayWriter charArrayWriter = new CharArrayWriter(); 12 //字符數組Writer 13 14 public HttpCharacterResponseWrapper(HttpServletResponse response) { 15 super(response); 16 // TODO Auto-generated constructor stub 17 } 18 19 public PrintWriter getWriter(){//覆蓋父類方法 20 return new PrintWriter(charArrayWriter); 21 }//返回字符數組Writer,緩存內容 22 23 public CharArrayWriter getCharArrayWriter() { 24 return charArrayWriter;//getter方法 25 } 26 }View Code
該類覆蓋了getWriter()方法,當servlet中使用該response對象調用getWriter()方法來輸出內容時,內容將會被輸出到CharArrayWriter對象中,達到緩存效果。
Filter中需要自定義的response傳進servlet中,代碼如下:OutputReplaceFilter.java
1 package com.yzj.filter; 2 3 import java.io.FileInputStream; 4 import java.io.FileNotFoundException; 5 import java.io.IOException; 6 import java.io.PrintWriter; 7 import java.util.Properties; 8 9 import javax.servlet.Filter; 10 import javax.servlet.FilterChain; 11 import javax.servlet.FilterConfig; 12 import javax.servlet.ServletException; 13 import javax.servlet.ServletRequest; 14 import javax.servlet.ServletResponse; 15 import javax.servlet.http.HttpServletResponse; 16 import com.yzj.response.HttpCharacterResponseWrapper; 17 18 public class OutputReplaceFilter implements Filter { 19 20 private Properties pp = new Properties(); 21 //非法詞、敏感詞,配置在初始化參數中 22 23 @Override 24 public void destroy() { 25 // TODO Auto-generated method stub 26 27 } 28 29 @Override 30 public void doFilter(ServletRequest request, ServletResponse response, 31 FilterChain chain) throws IOException, ServletException { 32 HttpCharacterResponseWrapper responseWrapper = new HttpCharacterResponseWrapper((HttpServletResponse) response); 33 34 chain.doFilter(request, responseWrapper); //doFilter,使用自定義response 35 36 String output = responseWrapper.getCharArrayWriter().toString(); 37 //得到responseWrapper輸出內容 38 39 for(Object obj:pp.keySet()){ 40 //遍歷所有敏感詞 41 String key = (String) obj; 42 output = output.replace(key, pp.getProperty(key));//替換敏感詞 43 } 44 PrintWriter out = response.getWriter(); 45 //通過原來的response的getWriter()方法輸出 46 out.write(output); 47 out.println("<!--Generated at"+new java.util.Date()+"-->"); 48 49 } 50 51 @Override 52 public void init(FilterConfig filterConfig) throws ServletException { 53 //初始化時 54 String file = filterConfig.getInitParameter("file"); //配置文件的位置 55 String realPath = filterConfig.getServletContext().getRealPath(file); 56 //文件得實際位置 57 58 try { 59 pp.load(new FileInputStream(realPath)); 60 } catch (FileNotFoundException e) { 61 // TODO Auto-generated catch block 62 e.printStackTrace(); 63 } catch (IOException e) { 64 // TODO Auto-generated catch block 65 e.printStackTrace(); 66 } 67 68 } 69 70 }View Code
本例中,自定義的response只是一個“偽裝”的response。Servlet會通過它輸出內容到客戶端,但是它的內容只是將內容緩存起來了,並沒有真正輸出到客戶端。最終輸出到客戶端還是通過原來的response完成。
非法詞庫配置在properties文件中,通過Filter初始化參數傳給內容替換Filter。該properties文件內容如下:sensitive.properties
1 #amend 2 Chna = China 3 www.baidu.com.cn = ww.baidu.com 4 5 #replace 6 色情 = ** 7 情色 = ** 8 賭博 = **View Code
內容替換Filter的配置文件。web.xml
1 <filter> 2 <filter-name>OutputReplaceFilter</filter-name> 3 <filter-class> 4 com.yzj.filter.OutputReplaceFilter 5 </filter-class> 6 <init-param> 7 <param-name>file</param-name> 8 <param-value>/WEB-INF/sensitive.properties</param-value> 9 </init-param> 10 </filter> 11 12 <filter-mapping> 13 <filter-name>OutputReplaceFilter</filter-name> 14 <url-pattern>*.jsp</url-pattern> 15 </filter-mapping>View Code
jsp文件代碼如下:replace.jsp
1 <%@ page language="java" contentType="text/html; charset=UTF-8" %> 2 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 3 <html> 4 <head> 5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 6 <title>Insert title here</title> 7 </head> 8 <body> 9 10 Chna <br/> 11 <br/> 12 色情 <br/> 13 賭博 <br/> 14 情色 <br/> 15 <br/> 16 www.baidu.com.cn <br/> 17 18 </body> 19 </html>View Code