21,过滤器
在Servlet/JSP中要实现过滤器,必须实现Filter接口,并使用@WebFilter标注或在web.xml中定义过滤器,让容器知道该加载哪些过滤器类。
import java.io.IOException;
public interface Fileter{
public void init (FilterConfig filterConfig) throws ServletException;
public void doFilter(ServletRequest request,ServletResponse response,FileterChain chain) throws IOException,ServletException;
public void destroy();
}
FilterConfig类似于Servlet接口init()方法参数上的ServletConfig,FilterConfig是实现Filter接口的类上使用标注或web.xml中过滤器设置信息的代表对象。如果在定义过滤器
时设置了初始参数,则可以通过FilterCOnfig的getInitParameter()方法来取得初始参数。
Filter接口的doFIlter()方法则类似于Servlet接口的service方法。当请求来到容器,而容器发现调用Servlet的service()方法前,可以应用某过滤器时,就会调用该过滤器
的doFilter()方法。可以在doFileter()方法中进行service()方法的前置处理,而后决定是否调用FilterChain的doFIlter()方法。
如果调用了FIlterChain的doFilter()方法,就会运行下一个过滤器,如果没有下一个过滤器,就调用请求目标Servlet的Service()方法。如果因为某个情况而没有调用
FIlterChain的doFilter(),则请求就不会继续交给接下来的过滤器或目标Servlet,这时就是所谓的拦截请求。
FilterChain的doFilter()实现,概念上类似:
Filter filter=filterIterator.next();
if(filter!=null){
fileter.doFilter(requesr,response,this);
}
else{
targetServlet.service(request,response);
}
在陆续调用完FIlter实例的doFilter实例的doFilter()仍至Servlet的service()之后,流程会以堆栈顺序返回,所以在FilterChain的doFilter()运行完毕后,就可以针对service()
方法做后续处理。
//service()前置处理
chain.doFIlter(request,response);
//service()后续处理
如果在调用FIlter的doFilter()期间,因故抛出UnavailableException,此时不会继续下一个Filter,容器可以检验异常的isPermanent(),如果不是true,则可以在稍后重试Filter。
Servlet/JSP提供的过滤器机制,其实是JavaEE设计模式中INterceptor FIlter模式的实现。如果希望可以弹性地抽换某功能的前置与后置处理元件,就可以应用Interceptor Filter
模式。