Java for Web学习笔记(三九):Filter(1)用途、定义和顺序

    xiaoxiao2021-03-25  113

    Filter的用途

    Filter可以用于以下方面:

    记录request和response的log进行认证和授权进行压缩和加压,非HTTPS的加密和解密错误处理。对于tomcat,出现错误通常会给出一个500的页面,还有错误诊断信息,对于一个公众服务,这些诊断信息可能会向黑客泄漏一些敏感信息,通过Filter,我们可以用try{}catch(){},将这些诊断信息记录在log中,而向公众展现一个通用的错误页面。

    Filter可以在Servlet执行前以及执行后进行相应的动作,而不仅仅在执行前。

    定义Filter

    通过web.xml定义

    和定义Servlet相似。在匹配条件中,可以指定url,可以指定servlet名字,也可以指定分派方式dispatcher。dispatcher有以下之中模式:

    REQUEST:普通模式,来自客户端的请求FORWARD:通过RequestDispatcher的forward(),或者<jsp:forward>INCLUDE:通过RequestDispatcher的include(),或者<jsp:include>ERROR:请求错误页面来处理HTTP错误,例如404,500ASYNC:来自AsyncContext的异步请求 <filter> <filter-name>myFilter</filter-name> <filter-class>com.abc.MyFilter</filter-class> </filter> <filter-mapping> <filter-name>myFilter</filter-name> <url-pattern>/foo</url-pattern> <url-pattern>/bar/*</url-pattern> <servlet-name>myServlet</servlet-name> <dispatcher>REQUEST</dispatcher> <dispatcher>ASYNC</dispatcher> </filter-mapping>

    如果没有指定dispacher,缺省为REQUEST。

    Filter的init()将在web app启动时执行,在ServletContextListeners的初始化之后,执行的顺序按web.xml中<filter>定义的顺序。

    使用Annotation定义

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

    使用annotation的主要问题是无法确定filter的执行顺序,通常只在单个filter的请求下使用。但是,基于某些原因,例如我们需要通过ProGuard进行扰码,不适用web.xml的定义方式,我们还可以在代码中进行设定。在大型的web app中很少使用annotation来定义,一般采用部署描述(web.xml)或/和代码定义。

    在代码中定义

    前面提到filter的初始化在ServletContextListener的初始化之后执行,因此定义filter,需要在ServletContextListener的初始化过程中定义,还可以在ServletContainerInitializer的onStartup()中定义。

    @WebListener public class GlobalLisener implements ServletContextListener { ...... public void contextInitialized(ServletContextEvent event) { ServletContext context = event.getServletContext(); //【1】通过addFilter()来顺序添加filter FilterRegistration.Dynamic registration = context.addFilter("myFilter", new MyFilter()); //【2】设置filter的匹配 // -- 第一个参数为null,则是缺省的REQUEST模式 // -- 第二个参数false表明在代码设置的filter先于web.xml中设置的filter,true则是先web.xml定义的filter后代码设置的。 registration.addMappingForUrlPatterns( EnumSet.of(DispatcherType.REQUEST, DispatcherType.ASYNC),false, "/foo", "/bar/*" ); registration.addMappingForServletNames( EnumSet.of(DispatcherType.REQUEST, DispatcherType.ASYNC),false, "myServlet" ); } }

    Filter的顺序

    前面我们了解如何通过web.xml和代码设定filter的优先顺序。filter可以通过url或者servlet名字进行匹配。在实际的匹配中,先执行满足url匹配的filter,如果有多个,则按filter的优先顺序,接着执行满足servlet名字匹配的filter,如果有多个,则按filter的优先顺序。例:FilterA优先于filterB,对于某个http请求,filterA是serveltName匹配,filterB是url匹配,则先执行filterB。

    相关链接: 我的Professional Java for Web Applications相关文章

    转载请注明原文地址: https://ju.6miu.com/read-9754.html

    最新回复(0)