Filter(过滤器)
过滤器的作用
在一个请求去访问某个资源的时候,filter可以在这个请求访问到这个资源之前,把请求拦下,然后做出一系列的处理或者判断(比如编码的转换,信息的过滤、权限的判断、是否已经登录的验证等等),最后filter再决定是否要让这个请求去访问那个资源.
编写filter过滤器
写一个java类,然后实现javax.Servlet.Filter接口:
这个接口中有三个方法:
init destroy doFilter
init:这个过滤器类被服务器创建对象的时候会调用到这个方法。
destroy:过滤器对象被销毁的时候会调用这个方法。
doFilter:当过滤器拦截到请求的时候,会调用这个doFilter.,其中最重要的doFilter方法有三个参数public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain), FilterChain是一个接口,表示过滤器链,这个接口中只有一个方法
public interface FilterChain { public void doFilter(ServletRequest request, ServletResponse response)throws IOException, ServletException; }
同一个请求有可能要依次的通过俩个或者多个过滤器,在web中把这样多个过滤器看做一个过滤器链条对象,就是用这个FilterChain类型的对象来表示。chain.doFilter(req,res)表示把当前的req和res传给这个过滤器链条中的下一个过滤器进行过滤,如果说链条中已经没有下一个过滤器,那么就把这次访问放行,让它去访问它真正要访问的资源.
在web.xml中配置filter过滤器
注意<filter>标签中也能使用<init-param>给过滤器传值
<filter> <filter-name>encodingFilter</filter-name> <filter-class>com.briup.filter.EncodingFilter</filter-class> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
其中<url-pattern></url-pattern>有四种配置方式
第一种 精确匹配
<url-pattern>/test_servlet</url-pattern>
表示此拦截器只会拦截/test_servlet这一个路径
第二种 扩展名匹配
<url-pattern>*.html</url-pattern>
表示此拦截器只会拦截后缀名是.html的路径
第三种 路径匹配
<url-pattern>/test/*</url-pattern>
表示此拦截器拦截/test路径下的所有资源
注意:路径和扩展名匹配无法同时设置,比如下面的三个<url-pattern>都是非法的,如果设置,启动tomcat服务器会报错。
<url-pattern>/test/*.html</url-pattern> <url-pattern>/*.html</url-pattern> <url-pattern>he*.html</url-pattern>
另外<url-pattern>/aa/*/bb</url-pattern>这个是精确匹配,url必须是 /aa/*/bb,这里的*不是通配的含义
第四种 匹配任意的url
<url-pattern>/*</url-pattern>
注意:<filter-mapping>标签中,有一个子标签<dispatcher>,该标签可以指定,目标资源是以什么方式被访问的时候会被拦截器拦截,默认值是REQUEST:
<filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> </filter-mapping>
<dispatcher>标签中可以填写的值有以下内容:
Servlet2.5中
REQUEST——浏览器直接访问目标资源时,filter进行拦截(默认配置)
例如:浏览器地址栏中直接输入地址进行访问
FORWARD——目标资源是通过RequestDispatcher的forward访问时,filter进行拦截
例如:浏览器地址栏中输入地址访问servletA,然后在servletA中进行forward跳转到servletB中,这时对servletB的访问就会被filter拦截
注意1:这时候最终返回的响应中的响应体的内容完全是由servletB进行设置的,例如在servletB中写进去一句字符串helloworld,或者是一个页面。
注意2:如果servletA中,在跳转至servletB之前,也设置了响应了内容,那么这个内容是会被忽略掉的
注意3:out.flush()方法之后就不能再调用forward进行跳转了,否则会有异常:Cannot forward after response has been committed
INCLUDE——目标资源是通过RequestDispatcher的include方法调用时,filter进行拦截
例如:浏览器地址栏中输入地址访问servletA,然后在servletA中进行include方法把请求转发到servletB中,这时对servletB的访问就会被filter拦截
注意1:这时候最终返回的响应中的响应体的内容是有servletA和servletB俩个servlet共同设置的,例如servletA中写进去一句字符串hello,然后servletB中又写进去一个world
注意2:out.flush()方法之后可以调用include进行跳转
ERROR——目标资源是通过声明式异常处理机制时,过滤器将被调用,filter进行拦截
例如:如果出现404异常则跳转到/404.html页面中
<error-page> <error-code>404</error-code> <location>/404.html</location> </error-page> 或者 <error-page> <error-type>java.io.FileNotFoundException</error-type> <location>/not_found.html</location> </error-page>
Servlet3.0在Servlet2.5基础上加了下面的一项:
ASYNC——支持异步处理
如果有多个过滤器,并且多个过滤器拦截的路径有相同的部分,就有一些路径被会这多个过滤器共同拦截,那么过滤器的顺序是按照web.xml中配置的顺序从上到下执行的,如果是使用的注解@WebFilter的形式来配置的过滤的话,那么多个过滤器拦截同一个路径的执行顺序是过滤器类名的首字母的顺序来执行的。
监听器(Listener)
监听器的作用
监听器用于监听web程序中的事件,例如创建、修改、删除Session、request、application等,并触发响应的事件。
监听器的设计使用的是观察者模式,事件发生的时候会自动触发该事件对应的Listener。
监听器主要用于对 Session、request、application进行监控。
监听 request、Session、application 的创建和销毁,分别为:ServletRequestListener、HttpSessionListener、ServletContextListener
监听request、session、application三个对象中属性变化,分别为:ServletRequestAttributeListener 、HttpSessionAttributeListener、ServletContextAttributeListener
监听Session对象里面存放着的其他对象,例如,把User对象存到了session中,下面监听器监听的是User对象,它们分别为:HttpSessionBindingListener接口和HttpSessionActivationListener接口,注意:这两类 Listener 监听的是Session 内的对象,而非 Session 本身,接口是让实体类进行实现的(例如User类或者Book类等),使用这种情况不需要在 web.xml中配置。
在web.xml中配置Listener监听器:
<listener> <listener-class>com.briup.listener.TestListener</listener-class> </listener>
或者使用注解@WebListener也可以