有時候需要對網站進行控制,防止輸出非法內容或者敏感信息。這時我們可以使用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