[有书共读]JavaWeb高级编程

JavaWeb高级编程 -- 篇9

使用过滤器改进应用程序

过滤器是可以拦***问资源的请求、资源的响应或者同时拦截两者的应用组件。
过滤器可以检测和修改请求和响应,它们甚至可以拒绝、重定向或转发请求。
过滤器在初始化时将调用init方法,它可以访问过滤器的配置、初始化参数和SevletContext,正如Servlet的init方法一样。当请求进入过滤器中时,doFilter方法将会被调用,它提供了对ServletRequest、ServletResponse和FilterChain对象的访问。在doFilter之中,可以拒绝请求或者调用FilterChain对象的doFilter方法,可以修改请求和响应,并且可以封装请求和响应对象。
尽管只有一个Servlet可以处理请求,但可以使用许多过滤器拦截请求。
如同Servlet一样,过滤器可以被映射到URL模式,这会决定哪个过滤器将拦截某个请求。在任何匹配某个过滤器的URL模式的请求在被匹配的Servlet处理之前将首先进入该过滤器。
在声明和映射过滤器拦截请求之前,必须如同Servlet一样声明和映射它们。传统的方式是在部署描述符中使用和元素。必须至少包含一个名字和类名,它还可以包含描述、显示名称、图标以及一个或多个初始化参数。


 myFilter
    com.wrox.MyFilter

与Servlet不同的是,过滤器不可以在第一个请求到达时加载。过滤器的init方法总是在应用程序启动时调用。
在声明了过滤器之后,可以将它映射到任意数目的URL或Servlet名称。


 myFilter
    /foo
    /bar/*
    myServlet
    REQUEST
    ASYNC

过滤器将会响应所有相对于应用程序的URL/foo和/bar/*的请求,以及任何最终由Servlet/myServlet处理的请求。这里的两个元素意味着它可以响应普通的请求和由AsyncContext派发的请求。有效的类型有:REQUEST、FORWARD、INCLUDE、ERROR和ASYNC。

如同Servlet一样,可以注解声明和映射过滤器。

@WebFilter(
 filterName = "myFilter",
    urlPatterns = { "/foo","/bar/*" },
    servletNames = { "myServlet" },
    dispatcher = { DispatcherType.REQUEST, DispatcherType.ASYNC }
)
public class MyFilter implements Filter{
 ...
}

使用注解声明和映射过滤器的主要缺点是:不能对过滤器链上的过滤器进行排序。如果希望在不使用部署描述符的情况下控制过滤器的执行顺序,那么需要使用编程式配置。

如同Servlet、***和其他组件一样,可以在ServletContext中以编程的方式配置过滤器。不使用部署描述符和注解,调用ServletContext的方法注册和映射过滤器即可。因为这必须要在ServletContext结束之前完成,所有通常需要在ServletContextListener的contextInitialized方法中也实现。
过滤器顺序决定了过滤器在过滤器链中出现的位置,这反过来也决定了过滤器什么时候处理请求。
使用注解时无法对过滤器进行排序。
定义过滤器顺序是很简单的:匹配请求的过滤器将按照它们出现在部署描述符或者编程式配置中的顺序添加到过滤器链中。不同的请求将匹配不同的过滤器,但使用的过滤器顺序总是相同的。URL映射的过滤器优先级比Servlet名称映射到的过滤器高。如果两个过滤器都可以匹配某个请求,一个是URL模式而另一个是Servlet名称,那么在过滤器链中,由URL模式匹配的过滤器总是出现由Servlet名称匹配的过滤器之前。

如果使用AsyncContext直接处理响应对象,代码将在所有过滤器的范围之外执行。不过,如果使用AsyncContext的dispatch方法在内部将请求转发到某个URL,那么映射到ASYNC请求的过滤器可以拦截该内部转发请求,并应用必要的额外逻辑。

#Java##读书笔记#
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务