Filter过滤器就像防火墙一样,根据你的设置可以将对服务器的请求和服务器的响应进行过滤。编写自己的过滤器需要实现Filter接口,实现里面的init()、doFilter()和destroy()这三个方法。init()方法由WEB容器来调用,初始化过滤器。当容器接收到Url映射到过滤器的每次请求都会调用方法doFilter()方法。容器将destroy()方法作为过滤器对象的{zh1}一个方法来调用。过滤发言,我们要用到HttpServletRequestWrapper包装器,继承该类,重写该类的getParameter()方法,我们就可以在使用request.getParameter()的时候对发言进行过滤操作了。在过滤器里面我们通常使用FilterChain的doFilter方法来将请求继续传递到下一个组件去处理,我们所要做的就是在传递请求的时候将原来的ServletRequest替换为我们自定义的实现HttpServletRequestWrapper包装器的类,就可以实现过滤了。
首先创建我们自己的请求类,重写getParameter()方法,在该方法中做发言过滤的主要工作。因为我们通常想要过滤的语句有很多,不可能在程序中写死了,而且将来可能又有我们想过滤的语句,所以我们将那些要过滤的句子存放到文件里面如:
很好,很强大
瓜娃子
很黄,很强大
很黄
暴力
为了减少读取文件时的麻烦,语句的存放按一定的方式来存放。因为使用RandomFileAccess的readLine()一次刚好可以读取一行,所以就采用了上面的存放方式。在容器调用过滤器的init()方法时就将这些语句读取,并放置在一个上下文对象的属性里面,这里使用ArrayList集合来存放。为了字符编码的统一,将所有字符都编码为UTF-8编码,可以减少不必要的麻烦。
public void init(FilterConfig arg0) throws ServletException
{
// TODO Auto-generated method
stub
RandomAccessFile raf =
null;
List<String>wordsList
= new ArrayList<String>();
ServletContext context =
arg0.getServletContext();
String filePath =
context.getRealPath("/WEB-INF/words.txt");
try {
raf = new
RandomAccessFile(new File(filePath),"r");
String str =
null;
while((str =
raf.readLine()) !=
null){//将字符串都转换为UTF-8编码,便于和从浏览器发送过来的字符(浏览器发送过来的字符是按ISO8859-1编码的,将其也按UTF-8编码格式编码)
byte[]
bys = str.getBytes("ISO8859-1");
str
= new String(bys,"utf-8");
wordsList.add(str);
}
context.setAttribute("filter",
wordsList);
} catch (Exception e) {
// TODO
Auto-generated catch block
e.printStackTrace();
}finally{
try {
raf.close();
} catch
(IOException e) {
//
TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(wordsList);
}
接下来就是继承HttpServletRequestWrapper包装类,重写方法getParameter(),在该方法中做字符过滤处理。class
MyHttpRequest extends HttpServletRequestWrapper{
private HttpServletRequest
request;
public
MyHttpRequest(HttpServletRequest request) {
super(request);
this.request
= request;
}
public String
getParameter(String name){
String value
= null;
List<String>list
= null;
value =
request.getParameter(name);
if(value ==
null){
return
null;
}
try {
byte[]
str = value.getBytes("ISO8859-1");//先将浏览器发送过来的字符按UTF-8进行编码
value
= new String(str,"utf-8");
list
=
(List<String>)request.getSession().getServletContext().getAttribute("filter");
value
= value.replaceAll(" ",
"");//将空格替换掉,防止“很
黄
很 暴 力”的情况被忽略掉
for(int
i=0;i<list.size();i++){
if(value.contains(list.get(i))){//将过滤字符集中出现的句子全部用“******”替换掉
value
= value.replaceAll(list.get(i), "******");
}
}
} catch
(UnsupportedEncodingException e) {
//
TODO Auto-generated catch block
e.printStackTrace();
}
return
value;
}
}
接下来只需在过滤器调用doFilter(request,response)中的参数request替换为我们自定义的request类型就可以了。public
void doFilter(ServletRequest arg0, ServletResponse arg1,
FilterChain
arg2) throws IOException, ServletException {
// TODO Auto-generated method
stub
HttpServletRequest request =
(HttpServletRequest)arg0;//使用自定义请求类型来替换原来的类型
arg2.doFilter(new
MyHttpRequest(request), arg1);
}
{zh1}在web.xml文件中注册过滤器,如果要监听所有就将<url-pattern>写为/*。
<filter>
<filter-name>filtwords</filter-name>
<filter-class>com.apple.WordsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>filtwords</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
程序简单,有待完善。