内容替换Filter

      有时候需要对网站进行控制,防止输出非法内容或者敏感信息。这时我们可以使用filter来进行内容替换,其工作原理为,在Servlet将内容输出到response时,response将内容缓存起来,在Filter中进行替换,然后再输出到客户浏览器。由于默认的response并不能严格的缓存输出内容,因此需要自定义一个具备缓存功能的response。

      可以通过扩展javax.servlet.http.HttpServletResponseWrapper类来实现自定义response。该类实现了javax.servlet.http.HttpServletResponse接口的所有方法,根据需要覆盖其中相应的方法即可,代码如下:HttpServletResponseWrapper.java

内容替换Filter内容替换Filter

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

内容替换Filter内容替换Filter

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

内容替换Filter内容替换Filter

#amend
 Chna = China
 www.baidu.com.cn = ww.baidu.com
 
 #replace 
 色情 = **
 情色 = **
 赌博 = **
View Code

    内容替换Filter的配置文件。web.xml

内容替换Filter内容替换Filter

<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

内容替换Filter内容替换Filter

<%@ 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

相关推荐