一、过滤器配置web.xml
<filter>
<filter-name>GuestbookFilter</filter-name>
<filter-class>test.GuestbookFilter</filter-class>
<init-param>
<!-- 配置不雅字句内容的替换文件,内容如:fuck=****,每行一句 -->
<param-name>word_file</param-name>
<param-value>/WEB-INF/word.txt</param-value>
</init-param>
</filter>
<filter-mapping>
<!-- 存储过滤 -->
<filter-name>GuestbookFilter</filter-name>
<url-pattern>/process.jsp</url-pattern>
</filter-mapping>
<filter-mapping>
<!-- 显示过滤 -->
<filter-name>GuestbookFilter</filter-name>
<url-pattern>/index.jsp</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
二、过滤器编写GuestbookFilter.java,利用MyRequestWrapper和MyResponseWrapper来替换请求中的特殊字符和响应中的不雅字句
package test;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class GuestbookFilter implements Filter
{
private static final String WORD_FILE="word_file";
HashMap<String,String> hm=new HashMap<String,String>();
/**
* 在init()方法中,读取保存了不雅字句和替换内容的文件,
* 并以不雅字句作为key,替换内容作为value,保存到Hashmap对象中。
*/
public void init(FilterConfig filterConfig) throws ServletException{
String configPath=filterConfig.getInitParameter(WORD_FILE);
ServletContext sc=filterConfig.getServletContext();
String filePath=sc.getRealPath(configPath);
try{
FileReader fr=new FileReader(filePath);
BufferedReader br=new BufferedReader(fr);
String line;
while(null!=(line=br.readLine())){
String[] strTemp=line.split("=");
hm.put(strTemp[0],strTemp[1]);
}
}catch(IOException ie){
throw new ServletException("读取过滤文件信息出错!");
}
}
public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)
throws IOException, ServletException{
HttpServletRequest httpReq=(HttpServletRequest)request;
HttpServletResponse httpResp=(HttpServletResponse)response;
//得到请求和响应对象的封装类对象。
MyRequestWrapper reqWrapper=new MyRequestWrapper(httpReq);
MyResponseWrapper respWrapper=new MyResponseWrapper(httpResp);
chain.doFilter(reqWrapper,respWrapper);
String content = new String(respWrapper.toByteArray());
String result=replaceText(content);
httpResp.setContentType("text/html;charset=GB2312");
PrintWriter out = httpResp.getWriter();
out.println(result);
out.close();
}
/**
* 对内容中的不雅字句进行过滤。
*/
public String replaceText(String content) throws IOException{
StringBuffer sb=new StringBuffer(content);
Set keys=hm.keySet();
Iterator it=keys.iterator();
while(it.hasNext()){
String key=(String)it.next();
int index=sb.indexOf(key);
if(-1!=index){
sb.replace(index,index+key.length(),(String)hm.get(key));
}
}
return sb.toString();
}
public void destroy(){}
}
三、请求参数过滤MyRequestWrapper.java,替换请求中的特殊字符
package test;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
public final class MyRequestWrapper extends HttpServletRequestWrapper{
public MyRequestWrapper(HttpServletRequest request){
super(request);
}
/**
* 覆盖基类的getParameter()方法,对请求参数的值进行过滤。
*/
public java.lang.String getParameter(java.lang.String name){
String value=super.getParameter(name);
if(null!=value)
return toHtml(value.trim());
else
return null;
}
/**
* 将特殊字符转换为对应的实体引用或字符引用。
*/
private String toHtml(String str){
if(str==null)
return null;
StringBuffer sb = new StringBuffer();
int len = str.length();
for (int i = 0; i < len; i++){
char c = str.charAt(i);
switch(c){
case ' ':sb.append(" ");break;
case '\n':sb.append("<br>");break;
case '\r':break;
case '\'':sb.append("'");break;
case '<': sb.append("<");break;
case '>':sb.append(">");break;
case '&':sb.append("&");break;
case '"':sb.append(""");break;
case '\\':sb.append("\");break;
default:sb.append(c);
}
}
return sb.toString();
}
}
四、对响应数据进行过滤MyResponseWrapper.java,替换响应中的不雅字句,用ByteArrayServletOutputStream类的对象替换Web容器中的对象
package test;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class MyResponseWrapper extends HttpServletResponseWrapper{
private ByteArrayOutputStream baos;
private ByteArrayServletOutputStream basos;
private PrintWriter pw;
public MyResponseWrapper(HttpServletResponse response){
super(response);
//创建ByteArrayOutputStream对象。
baos=new ByteArrayOutputStream();
//用ByteArrayOutputStream对象作为参数,
//构造ByteArrayServletOutputStream对象。
basos=new ByteArrayServletOutputStream(baos);
//用ByteArrayOutputStream对象作为参数,
//构造PrintWriter对象。
pw=new PrintWriter(baos);
}
public PrintWriter getWriter(){
return pw;
}
public ServletOutputStream getOutputStream(){
return basos;
}
/**
* 以字节数组的形式返回输出流缓冲区中的内容。
*/
public byte[] toByteArray(){
return baos.toByteArray();
}
}
五、替换Web容器中的ServletOutputStream对象ByteArrayServletOutputStream.java
package test;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.servlet.ServletOutputStream;
//用该类的对象替换HttpServletResponse.getOutputStream()方法返回的ServletOutputStream对象
public class ByteArrayServletOutputStream extends ServletOutputStream{
ByteArrayOutputStream baos;
ByteArrayServletOutputStream(ByteArrayOutputStream baos){
this.baos = baos;
}
public void write(int data) throws IOException{
baos.write(data);
}
}