Filter介绍:
    Filter在项目中经常可以用到,通常配置在web.xml中。是服务器端的一个组件,对于用户的请求和响应数据进行过滤操作,控制是否让用户访问到对应的web资源。常用于编码更改、权限控制等操作。
 
过滤器的执行顺序:
配置方式:web.xml
  1. <!--filter过滤器-->
  2. <filter>
  3. <!--filter名称-->
  4. <filter-name>myCharacterFilter</filter-name>
  5. <!--filter处理的类-->
  6. <filter-class>com.filter.MyCharacterFilter</filter-class>
  7. <!--初始化参数-->
  8.     <init-param>
  9. <param-name>defaultCharset</param-name>
  10. <param-value>UTF-8</param-value>
  11. </init-param>
  12. </filter>
  13. <!--过滤器映射-->
  14. <filter-mapping>
  15. <!--和过滤器名相同-->
  16. <filter-name>myCharacterFilter</filter-name>
  17. <!--拦截的路径-->
  18. <url-pattern>*.do</url-pattern>
  19. </filter-mapping>
  20.  
  21. <!--映射多个不同路径,需要些多个<filter-mapping>-->
  22. <filter-mapping>
  23. <filter-name>myCharacterFilter</filter-name>
  24. <url-pattern>*.action</url-pattern>
  25. </filter-mapping>
    <filter>和<filter-mapping>的<filter-name>必须相同,多个不同路径需配置多个不同的<filter-mapping>。
    初始化参数可以写到<filter>的子节点<init-param>中,配置为键值对的方式,即<param-name>、<param-value>。
    Filter的实现类需要实现javax.servlet.Filter接口,默认重写init()、destroy()、doFilter()函数,这3个函数分别对应初始化、销毁、过滤这3个生命周期。
 

生命周期:
    实例化:web容器在部署web应用程序时对所有过滤器进行实例化。web容器回调它的无参构造方法。
    初始化:启动服务器时加载过滤器的实例,并自动调用init()函数。
    过滤:调用过滤器的doFilter()执行过滤,这个是过滤器的核心方法。
    销毁:停止服务时调用destroy()函数,销毁过滤器实例。
 
初始化参数获取:
    通过init()函数的参数FilterConfig对象,filter.getInitParameter("初始化参数key")能拿到初始化参数。
 

过滤器链:
    过滤器可以在web.xml中配置多个,满足对某一URL进行过滤条件时,会按照web.xml中配置的顺序进行执行,构成过滤器链。举例如下:
    请求某一URL执行过滤器MyCharacterFilter  和MyRoleFilter  。MyCharacterFilter  执行后会调用filterChain.doFilter()方法继续调用MyRoleFilter  过滤器。
    MyCharacterFilter  :
 MyRoleFilter  :
    
    控制台输出日志顺序:
          MyCharacterFilter   start==do
RoleFilter doFilter  ===  start
RoleFilter doFilter  ===  end

MyCharacterFilter   end==do

    
<filter-mapping>的特殊参数-dispatcher:
    此参数根据配置不同,支持不同类型的请求,可配置多个。
    REQUEST(默认值):从客户端直接请求过来会走这个过滤器,直接请求或redirect.sendRedirect("url");。
    FORWEARD:通过dispatcher的forward方法会走这个过滤器。request.getdispatcher("url").forward(request,response);或使用jsp指令 jsp:forward。
    INCLUDE:通过dispatcher的include()方法会走这个过滤器。request.getdispatcher("url").include(request,response);或使用jsp指令 jspinclude。
    ERROR:通过web.xml中<error-page>过来的请求会走这个过滤器。
    ASYNC(Servlet3.0添加了对另一种值的支持:异步处理)。原有的servlet需要处理完业务逻辑再相应,现在会开启另外一个线程单独处理业务逻辑,servlet线程委托其他线程处理业务逻辑,自己在不生成响应的情况下返回至容器,提高并发访问速度,减少服务器资源的占用。(下面有Demo)
 
Servlet3.0增加了对注解的支持,可以通过注解配置,不用在web.xml中配置。需要配合支持Tomcat7.0以上容器(支持servlet3.0)。配置内容:

 
 
这里做Demo的时候遇到了点问题,Dynamic Web Module版本是2.5,想改成3.0。发现没法改。(截图是改好的),可以点击右面的Runtimes,里面选择web容器,
注意此处只有web容器本身能支持servlet3.0才能选择3.0的Dynamic Web Module,比如Tomcat必须选择Tomcat7.0++,选择Apply-OK。然后再进来就能选择3.0了。
 
 
Servlet3.0特性之filter-dispatcher(ASYNC):
    1.业务逻辑处理之前调用AsyncContext ctx = req.startAsync();
  2.创建线程、传入ctx并调用具体业务逻辑。
  3.调用完成执行ctx的complete()函数。
Demo:
    ①.配置filter的dispatcher值为ASYNC,servlet的async-supported值为true.
  1. <filter>
  2. <filter-name>roleFilter</filter-name>
  3. <filter-class>com.filter.MyRoleFilter</filter-class>
  4. <init-param>
  5. <param-name>username</param-name>
  6. <param-value>www</param-value>
  7. </init-param>
  8. </filter>
  9. <filter-mapping>
  10. <filter-name>roleFilter</filter-name>
  11. <url-pattern>*.action</url-pattern>
  12. <dispatcher>ASYNC</dispatcher>
  13. </filter-mapping>
  14. <servlet>
  15. <description></description>
  16. <display-name>LoginServlet2</display-name>
  17. <servlet-name>LoginServlet2</servlet-name>
  18. <servlet-class>com.servlet.LoginServlet2</servlet-class>
  19. <async-supported>true</async-supported>
  20. </servlet>
  21. <servlet-mapping>
  22. <servlet-name>LoginServlet2</servlet-name>
  23. <url-pattern>/LoginServlet.action</url-pattern>
  24. </servlet-mapping>
    ②.servlet的处理逻辑中加入req.startAsync()函数,创建一个新的线程传入ctx对象并来执行业务逻辑。
  1. resp.setContentType("text/html;charset=UTF-8");
  2. PrintWriter pw = resp.getWriter();
  3. pw.println("进入servlet时间" + new SimpleDateFormat("yyyy-Mm-dd HH:mm:ss").format(new Date()));
  4. pw.flush();
  5. AsyncContext ctx = req.startAsync();
  6. new Thread(new Executor(ctx)).start();
  7. pw.println("离开servlet时间" + new SimpleDateFormat("yyyy-Mm-dd HH:mm:ss").format(new Date()));
  8. pw.flush();
    ③.线程的run()函数执行逻辑后调用ctx的complete()函数通知容器异步处理完成。
  1. //等待10s,模拟业务逻辑
  2. try {
  3. Thread.sleep(10000);
  4. PrintWriter pw = ctx.getResponse().getWriter();
  5. pw.println("业务逻辑处理完成时间"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
  6. pw.flush();
  7. this.ctx.complete();
  8. } catch (Exception e) {
  9. e.printStackTrace();
  10. }
   搞定,亲测结果OK。输出结果:
   直接输出(servlet已响应):进入servlet时间2015-1015-19 12:15:46 离开servlet时间2015-1015-19 12:15:46 
  大约10S后输出结果(单独开线程异步处理):业务逻辑处理完成时间2015-10-19 12:15:56
 
顺便提及servlet3.0的异步处理的监听器AsyncListener,这个接口监控如下4种事件:
  1. 异步线程开始时,调用 AsyncListener 的 onStartAsync(AsyncEvent event) 方法;
  2. 异步线程出错时,调用 AsyncListener 的 onError(AsyncEvent event) 方法;
  3. 异步线程执行超时,则调用 AsyncListener 的 onTimeout(AsyncEvent event) 方法;
  4. 异步执行完毕时,调用 AsyncListener 的 onComplete(AsyncEvent event) 方法。
 
要注册一个 AsyncListener,只需将准备好的 AsyncListener 对象传递给 AsyncContext 对象的 addListener() 方法即可,如下所示:
  1. ctx.addListener(new AsyncListener() {
  2. @Override
  3. public void onTimeout(AsyncEvent arg0) throws IOException {
  4. System.out.println("listener===超时");
  5. }
  6. @Override
  7. public void onStartAsync(AsyncEvent arg0) throws IOException {
  8. System.out.println("listener===开始");
  9. }
  10. @Override
  11. public void onError(AsyncEvent arg0) throws IOException {
  12. System.out.println("listener===异常");
  13. }
  14. @Override
  15. public void onComplete(AsyncEvent arg0) throws IOException {
  16. System.out.println("listener===完成");
  17. }
  18. });
     经过测试,发现onStartAsync()现这个函数没有被调用,没有找到原因!onComplete()正常被调用,onTimeout()debug的时候会打印出超时的信息。
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
        
 

Filter学习总结,顺便提及点servlet3.0异步filter和异步监听的更多相关文章

  1. 【SpringBoot】SpringBoot拦截器实战和 Servlet3.0自定义Filter、Listener

    =================6.SpringBoot拦截器实战和 Servlet3.0自定义Filter.Listener ============ 1.深入SpringBoot2.x过滤器Fi ...

  2. Servlet学习:(三)Servlet3.0 上传文件

    转: Servlet学习:(三)Servlet3.0 上传文件 2018年08月03日 11:57:58 iDark_CSDN 阅读数:362   一.注意事项 客户端(浏览器) 表单的提交方法必须是 ...

  3. java web学习总结(二十一) -------------------模拟Servlet3.0使用注解的方式配置Servlet

    一.Servlet的传统配置方式 在JavaWeb开发中, 每次编写一个Servlet都需要在web.xml文件中进行配置,如下所示: 1 <servlet> 2 <servlet- ...

  4. 小D课堂 - 零基础入门SpringBoot2.X到实战_第6节 SpringBoot拦截器实战和 Servlet3.0自定义Filter、Listener_24、深入SpringBoot过滤器和Servlet配置过滤器

    笔记 1.深入SpringBoot2.x过滤器Filter和使用Servlet3.0配置自定义Filter实战(核心知识)     简介:讲解SpringBoot里面Filter讲解和使用Servle ...

  5. SpringBoot拦截器和 Servlet3.0自定义Filter、Listener

    官方文档译文 Spring Boot 包括对嵌入式Tomcat,Jetty和Undertow服务器的支持.大多数开发人员使用适当的“Starter”来获取完全配置的实例.默认情况下,嵌入式服务器在 p ...

  6. 学习Android过程中遇到的问题及解决方法——电话监听

    也许有时你会有这样一个需求:通电话时有一个重要的事需要记下来或者和一个陌生人特别是大骗子通话时,这是就想如果能把通话录下来就方便多了.(这才是我写这个代码的目的!!!) 在此过程中,犯了一个很大的错误 ...

  7. SpringBoot2.0 监听器ApplicationListener的使用-监听ApplicationReadyEvent事件

    参考:http://www.shareniu.com/article/73.htm 一.需求是想将我的写一个方法能在项目启动后就运行,之前使用了redis的消息监听器,感觉可以照着监听器这个思路做,于 ...

  8. Vue学习笔记(二)动态绑定、计算属性和事件监听

    目录 一.为属性绑定变量 1. v-bind的基本使用 2. v-bind动态绑定class(对象语法) 3. v-bind动态绑定class(数组语法) 4. v-bind动态绑定style(对象语 ...

  9. Servlet3.0 新特性

    Servlet3.0 的注解 Servlet 允许开发人员采用注解的方式来配置 Servlet.Filter.Listener. Servlet3.0 规范在 javax.servlet.annota ...

随机推荐

  1. MapReduce编写的正确姿势

    先看一下目录结构 这里是job接口,负责参数的传递和定时的调用 下面的图是MR 程序相关的目录图片,其中MR的入口程序负责读取数据,并指定对应的Map.Reduce程序. 程序的流程 首先简单的说一下 ...

  2. Call requires API level 11 (current min is 8)报错

    新建一个Android Application Project,其中MainActivity.java中报错如下 Call requires API level 11(current min is 8 ...

  3. Jenkins 更换国内源

    jenkins插件清华大学镜像地址https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json1更换地址方法1.进入j ...

  4. stiff chemistry模型出现NaN错误

    通过定位可以看到,是usr_rates.f中出现了奇异值,因为我的代码中有这样一句话: 而同时我的ConH2在声明后没有赋初值,因此,当X_g(IJK,H2) < c_Limiter后,ConH ...

  5. Feel Good(两遍单调栈维护区间+前缀和)

    Bill is developing a new mathematical theory for human emotions. His recent investigations are dedic ...

  6. 原生js操作类名

  7. 选择IM云服务供应商

    选择IM云服务供应商,其实最重要是有三个因素:费用.技术稳定性.以及后续运维服务. 对于不少创业公司来讲,可能需要找到成本和稳定性的最佳平衡点.目前国内不少IM云服务产品都推出了免费服务项目或者一定期 ...

  8. 【实战】简述一次挖XSS的经历

    值守尤其是夜班真的是件痛苦的事情呀,献给还在值守岗位上奋斗的小伙伴们. 简单试了前面几个参数,发现c0-id这个参数值在响应包里有回显,截图如下: 把c0-id参数值改为xss,响应包内容也随之变化, ...

  9. CSAPP阅读笔记-32位64位的区别--来自第三章引言的笔记--P110

    仅从寻址上看,32位和64位机器能寻址的内存空间大小不同. 需要知道的是,计算机系统对存储器作了抽象,程序“认为”内存是一个很大的字节数组,然而实际上它是由多个硬件存储器和操作系统组合起来实现的. 程 ...

  10. jquery 属性选择器

    jquery 属性选择器   第一种根据属性选择E[attr] $("[title]").click().......... 即选择所有元素内 属性带有title的元素即<l ...