Filter技术在java web项目中的应用十分广泛,其之所以如此受欢迎跟它的强大功能是分不开的。而其中最重要的是它可以根据配置文件的设置情况改变一个request,并且能够修改经过你servlet处理后返回的response。在具体讲解Filter用法之前我们先来了解一下Filter技术的原理。首先我们先要明确一个观点,Filter并不不是一个servlet,它所能够做的事情仅仅是在请求到达servlet之前对请求预先进行处理,并且可以在请求被servlet处理后对response进行修改。更形象一点来说,Filter更像是由一个个过滤箱组成的链,它存在于web客户端与所请求资源之间(这里的请求资源可以暂时理解为jsp或者servlet),其过滤过程如下图所示:
对上图我们可以这样理解:当web端发送一个request的时候,这个request首先会被第一个Filter截获,经过第一个Filter的处理后,通过chain.doFilter()方法,这个被处理过的request继续向下传递然后被第二个Filter截获,经过第二个Filter的处理后,通过chain.doFilter()方法继续向下传递,直到被第n个Filter处理后这个request才能到到所要请求的资源,进而被处理。当request被所请求的资源处理完毕后,回传的response会依次经过第n个Filter,第(n-1)...第2个,直至第1个Filter,在回传的过程中该response也会依次被Filter处理,直至将最后的response返回到客户端。那么当过滤器执行的顺序是怎样的呢?当然这就和配置文件的Filter的配置顺序相关了,在提交一个请求的时候这个请求会根据配置文件中Filter的顺序依次执行(前提条件是这个请求符合这些Filter的过滤规则,一个请求可以被多个Filter过滤,同时一个过滤器也可以过滤多个请求)。下面我们就通过一个IP过滤实例来向大家介绍Filter的用法。本实例的功能是用来实现IP访问限制,也就是限制只有在某个网段范围内的IP能访问本系统。如本系统限制只有IP地址为192.168.24.*的电脑可以访问本系统,那么不在本网段范围内的电脑是无权对本系统进行访问的。闲话不多说了,看代码:
(1)web.xml配置文件中的Filter配置信息。在所设置的Filter中的过滤规则是对所有的jsp页面进行过滤,只要客户端电脑访问的是服务器端的jsp页面则将该request转入过滤程序。
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name></display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>FreeIpFilter</filter-name>
<filter-class>MyPackage.CharsetEncodingFilter</filter-class>
<init-param>
<param-name>FreeIPs</param-name>
<param-value>192.168.24.*</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>FreeIpFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
</web-app>
(2)实现Filter接口的java类。这是真正对request和response进行处理的地方。它的处理方式是如果客户端的IP地址在配置文件中所设置的IP地址的范围内,则允许访问,否则会跳到“NoRight.jsp”页面。
package MyPackage;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.omg.CORBA.Request;
/**
* 采用Filter统一处理字符集
* @author changshou
*
*/
public class CharsetEncodingFilter implements Filter {
//盛放从web.xml文件中取出的IP范围的值
private String freeIps;
@Override
//析构函数
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
//设置跳转页面
RequestDispatcher dispatcher=request.getRequestDispatcher("NoRight.jsp");
//将取得web.xml中IP范围的值按照“.”拆分成数组
String[] freeIpStr = freeIps.split("\\.");
//取得客户端的IP地址的值
String remoteIp = request.getRemoteAddr();
//将客户端的IP地址的值根据“.”拆分成数组
String[] remoteIpStr = remoteIp.split("\\.");
//定义一个布尔变量,如果该值为true则继续向下传递request,否则跳转到指定页面
boolean flag = true;
//定义一个整形变量,根据这个整形变量来确定循环的次数
int arrayNo = 0;
//该循环取得非“*”元素个数
for(int i=0;i<freeIpStr.length;i++){
if(!freeIpStr[i].equals("*")){
arrayNo++;
}
}
//该循环对客户端IP和xml文件中设置的IP范围进行核对,如果客户端IP在允许范围内则flag为true,否则为false
for(int i=0;i<arrayNo;i++){
if( Integer.parseInt(freeIpStr[i].trim().toString()) !=(Integer.parseInt(remoteIpStr[i].trim().toString())) ){
flag=false;
break;
}
}
//如果flag值为true,则继续传递request,否则进行页面跳转
if(flag){
chain.doFilter(request, response);
}else{
//System.out.println("非法IP");
dispatcher.forward(request,response);
}
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
//将取出的xml文件中的允许的IP范围的值赋值给freeIps变量
this.freeIps = filterConfig.getInitParameter("FreeIPs").trim();
}
}
Filter技术除了可以进行IP过滤之外,其其他常用功能还有日志记录,性能,安全,回话处理,XSLT转换以及侦测使用WAP协议的移动客户端的呼叫,并且可以将答复内容转换成WML各式等。Filter技术的灵活性其实远不止我们所说的这些,只有在实际的项目开发过程中不断的深入研究才能将Filter技术的灵活性真正发挥出来,增强组件的可重复性,增强web项目的可维护性。