创建、声明和映射过滤器

创建、声明和映射过滤器

创建过滤器如同实现Filter接口一样简单;
过滤器在初始化的时候调用init方法,它可以访问过滤器的配置、初始化参数和ServletContext;
应用程序在关闭时,调用过滤器的destroy方法;
当请求进入到过滤器时,会调用doFilter方法,它提供了对ServletRequest、ServletReponse和FilterChain对象的访问。

了解过滤器链

处理请求只有一个Servlet,但是可以使用很多过滤器拦截这个请求,也就是过滤器链。
容器接受请求,传递到过滤器当中,直到所有过滤器都完成,再传递给Servlet。
调用FilterChain.doFilter()将触发过滤器链的持续执行,如果当前Filter是过滤器链的最后一个,那么调用FilterChain.doFilter()将会把控制权返回到Servlet容器中,它将把请求交给Servlet。
如果当前过滤器没有调用FilterChain.doFilter(),那么过滤器链将会被中断,Servlet和所有其他剩余过滤器都无法再处理该请求。

映射到URL和Servlet名称

类似于Servlet,过滤器可以被映射到URL模式,这会决定哪个或哪些过滤器将拦截某个请求,通过URL模式,我们不仅可以拦截Servlet请求,还可以拦截资源,如CSS,JS,媒体等。然而映射到URL的方式显然是不方便的。可以映射到一个或者多个Servlet名称,如果匹配与某个Servlet,容器将寻找所有匹配该Servlet名称的过滤器,并将它们应用到请求上。

映射到不同的请求派发器类型

Servlet容器中,可以通过多种方式派发请求

  • 普通请求,这些请求来自于客户端,并包含了容器中特定Web应用程序的目标URL
  • 转发请求,当代码调用RequestDispatcher的forward方法或者使用标签时触发,尽管它们被关联到原始的请求,但是在内部作为单独的请求处理
  • 包含请求,使用标准或者调用RequestDispatcher的include方法时,会产生一个不同的与原始请求相关的内部包含请求(与<%@ include %>不同)
  • 错误资源请求,访问HTTP错误的错误页面的请求
  • 异步请求,这些请求是在处理任何其他请求的过程中,由AsyncContext派发的请求

使用部署描述符(web.xml)

就和Servlet一样,可以使用元素,元素至少包含一个名字和类名,它还可以包含描述,显示名称、图标以及一个或多个初始化参数。


 myFilter
 com.ww.myFilter

与Servlet不同的是,过滤器不可以在第一个请求到达时加载,过滤器的init方法总是在应用程序启动时调用:在ServletContextListener初始化之后,Servlet初始化之前,它们都将按照部署描述符中出现的顺序依次加载。

接下来,我们可以将刚刚声明的过滤器映射到URL或者Servlet名称中


 myFilter
 /foo
 /bar/*
 myServlet
 REQUEST
 ASYNC

有效的类型有REQUEST/FORWARD/INCLUDE/ERROR/ASYNC,如果没有指定,则默认只使用REQUEST派发器

使用注解

@WebFilter(
 filterName="",
 urlPattern={"/foo","/bar/*"},
 servletName={"myServlet"},
 dispatcherTypes={DispatcherTypes.REQUEST,DispatcherTypes.ASYNC}
)
public class MyFilter implements Filter

使用注解的缺点是不能对过滤器链上的过滤器进行排序。

使用编程式配置

如同Servlet、监听器和其他组件一样,可以在ServletContext中以编程的方式配置过滤器。
不使用部署描述符和注解,调用

@WebListener
public class Configurator implements ServletContextListener
{
    @Override
    public void contextInitialized(ServletContextEvent event)
    {
        ServletContext context = event.getServletContext();

        FilterRegistration.Dynamic registration =
                context.addFilter("requestLogFilter", new RequestLogFilter());
        registration.addMappingForUrlPatterns(null, false, "/*");

        registration = context.addFilter("compressionFilter",
                new CompressionFilter());
        registration.setAsyncSupported(true);
        registration.addMappingForUrlPatterns(null, false, "/*");
    }

    @Override
    public void contextDestroyed(ServletContextEvent event) { }
}

你可能感兴趣的:(JavaWeb高级编程读书笔记)