本文内容:

  • Listener
  • Filter

首发日期:2018-07-15


Listener

  • 监听器Listener负责监听事件的发生。我们能在事件发生后执行一些自定义的操作,这就是监听器的意义。
  • 监听器的本质是接口回调

分类:

  • 监听域对象的创建:监听三个域(request,session,context)的创建和销毁 【这里不讨论这些域什么时候创建什么时候销毁,因为太基础了。】
  • 监听三个域的数据的创建:监听三个域的数据的添加、移除、替换
  • 监听一个javabean在session域的存值的变化:监听某个javabean在session域的值的存储、移除、钝化、活化

使用:

1.监听域对象的创建与销毁:

    1. 定义一个类,实现对应的接口(右图是监听不同域需要实现的接口)。每一个接口主要有xxxInitialized函数和xxxDestroyed函数,xxxInitialized函数是当域对象创建的时候调用的,xxxDestroyed函数是当域对象销毁时调用的。
    2. 在web.xml中配置监听器

2.监听三个域的数据的创建

    1. 定义一个类,实现对应的接口(右图是监听不同域需要实现的接口)。每一个接口主要有attributeAdded函数、attributeReplaced函数和attributeRemoved函数,attributeAdded函数是当域对象中添加了属性的时候调用的,attributeReplaced函数是当域对象属性被替换的时候调用的,attributeRemoved函数是当域对象中属性被移除的时候调用的。
    2. 在web.xml中配置监听器

3.监听一个javabean在session域的存值的变化【这些监听器不需要在web.xml中配置】【由于它要有javabean实现对应接口采用功能。但面对的对象是session,换了一个session后,并且这个session没有那种数据,那么是不会有响应的】

    1. 定义一个javabean,实现对应的接口【对于钝化和活化还需要继承Serializable,使得能在硬盘中重新序列化到内存】
      1. 对于HttpSessionBindingListener接口,需要实现valueBound函数(当bean数据存储到session中时调用)和valueUnbound函数(当bean数据在session中移除时调用)
      2. 对于HttpSessionActivationListener接口,需要实现sessionDidActivate函数(当bean数据活化到内存时调用)和sessionWillPassivate函数(当bean数据钝化到硬盘时调用)。

题外话:什么是钝化和活化,以及怎么配置?

活化是指数据从硬盘到内存的过程;钝化是指数据从内存到硬盘的过程。

由于数据要使用,所以数据在内存中没有什么问题。但为什么需要钝化呢?这是因为内存是有限的,一些很久不用的数据不应该占用可贵的内存资源。

数据默认是内存中的,钝化需要进行配置(在tomcat里面 conf/context.xml 里面配置或在conf/Catalina/localhost/context.xml 配置或者在自己的web工程项目中的 META-INF/context.xml):【钝化的配置还有更多参数,这里不做详细讲解。有兴趣自查。】

<Context>
        <Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1" maxActiveSessions="1">
            <Store className="org.apache.catalina.session.FileStore" directory="session"/>
        </Manager>
</Context>

钝化已经配置好了,但如果想把数据重新取出来,bean必须实现Serializable.这样才能活化成功

实现HttpSessionBindingListener接口的例子:

  1. package work.domain;
  2.  
  3. import javax.servlet.http.HttpSessionBindingEvent;
  4. import javax.servlet.http.HttpSessionBindingListener;
  5.  
  6. public class User implements HttpSessionBindingListener {
  7. private int age;
  8. private String name;
  9. private String gender;
  10.  
  11. public User(int age, String name, String gender) {
  12. super();
  13. this.age = age;
  14. this.name = name;
  15. this.gender = gender;
  16. }
  17.  
  18. public int getAge() {
  19. return age;
  20. }
  21.  
  22. public void setAge(int age) {
  23. this.age = age;
  24. }
  25.  
  26. public String getName() {
  27. return name;
  28. }
  29.  
  30. public void setName(String name) {
  31. this.name = name;
  32. }
  33.  
  34. public String getGender() {
  35. return gender;
  36. }
  37.  
  38. public void setGender(String gender) {
  39. this.gender = gender;
  40. }
  41.  
  42. @Override
  43. public void valueBound(HttpSessionBindingEvent arg0) {
  44. System.out.println("bean数据被绑定了!");
  45. }
  46.  
  47. @Override
  48. public void valueUnbound(HttpSessionBindingEvent arg0) {
  49. System.out.println("bean数据被解绑了");
  50.  
  51. }
  52.  
  53. }

实现HttpSessionActivationListener接口的例子:

  1. package work.domain;
  2.  
  3. import java.io.Serializable;
  4.  
  5. import javax.servlet.http.HttpSessionActivationListener;
  6. import javax.servlet.http.HttpSessionEvent;
  7.  
  8. public class Person implements HttpSessionActivationListener,Serializable {
  9. private int age;
  10. private String name;
  11. private String gender;
  12.  
  13. public Person(int age, String name, String gender) {
  14. super();
  15. this.age = age;
  16. this.name = name;
  17. this.gender = gender;
  18. }
  19.  
  20. public int getAge() {
  21. return age;
  22. }
  23.  
  24. public void setAge(int age) {
  25. this.age = age;
  26. }
  27.  
  28. public String getName() {
  29. return name;
  30. }
  31.  
  32. public void setName(String name) {
  33. this.name = name;
  34. }
  35.  
  36. public String getGender() {
  37. return gender;
  38. }
  39.  
  40. public void setGender(String gender) {
  41. this.gender = gender;
  42. }
  43.  
  44. @Override
  45. public void sessionDidActivate(HttpSessionEvent arg0) {
  46. System.out.println("数据被活化了!");
  47.  
  48. }
  49.  
  50. @Override
  51. public void sessionWillPassivate(HttpSessionEvent arg0) {
  52. System.out.println("数据被钝化了!");
  53. }
  54.  
  55. }

作用:

  • 由于监听器是在事件发生后才触发的,所以你可以自己考虑需要在事件触发后执行哪些动作。
  • 有些人会在context创建后,执行某些初始化操作。
  • 有人会用session的创建来统计在线人数。【不过我觉得可能使用redis的bit可能更节省】

Filter

  • Filter是过滤器的意思。
  • 过滤器可以对请求进行过滤,过滤器要比Servlet早处理请求,只有过滤器对请求放行,Servlet才可以去处理请求。
  • 由于过滤器可以预先处理请求,所以可以把一些任务交给过滤器来做,从而减少Servlet的处理消耗。
  • 过滤器可以做到一些比如“和谐”、请求非法拒绝服务、统一数据编码等功能。总的来说,过滤器的意义是提前处理。

使用:

1.定义一个类, 实现Filter接口(是servlet包中的Filter)

    • init函数负责一些过滤器的初始化工作
    • doFilter函数负责过滤工作,它有三个参数request,response, chain,request和response如你所想,它跟servlet中的没什么区别,chain可以理解成过滤链,它有一个doFilter函数,调用的时候传入request和response,代表你对这个请求放行了!如果你不想放行就不要调用它!
    • destroy函数是过滤器销毁的时候调用的。
  1. package work.filter;
  2.  
  3. import java.io.IOException;
  4.  
  5. import javax.servlet.Filter;
  6. import javax.servlet.FilterChain;
  7. import javax.servlet.FilterConfig;
  8. import javax.servlet.ServletException;
  9. import javax.servlet.ServletRequest;
  10. import javax.servlet.ServletResponse;
  11.  
  12. public class MyFilter implements Filter {
  13. @Override
  14. public void destroy() {
  15. }
  16. @Override
  17. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  18. throws IOException, ServletException {
  19. System.out.println("证明一下,你经过了过滤器!");
  20. chain.doFilter(request, response);//这一步是放行!
  21. }
  22. @Override
  23. public void init(FilterConfig arg0) throws ServletException {
  24. // TODO Auto-generated method stub
  25.  
  26. }
  27.  
  28. }

2.在web.xml中配置过滤器:基本上与servlet的配置没什么区别,url-pattern也是一样的用法。

使用注意:

  1. 多个过滤器的通过顺序取决于web.xml中配置的过滤器的mapping的顺序 。
  2. 在多个过滤器过滤过程中,只要有一个不通过,那么后面的就不会再继续了。
  3. 过滤器会在服务端启动的时候就创建,会在服务端关闭时销毁。
  4. web.xml中的filter-mapping中可以配置一个属性dispatcher,它的值可以为REQUEST ,FORWARD,ERROR ,INCLUDE
    • 这些值的意义是:REQUEST 代表只要是请求就过滤;FORWARD代表过滤所有请求转向;ERROR代表过滤所有页面错误时的跳转;INCLUDE代表包含页面时就过滤。

小例子:

利用过滤器来统一请求数据的编码:

1.一般来说,对于post请求中的中文数据问题,可以使用request.setCharacterEncoding来解决,但如果每一个请求交给一个servlet来处理的话,就会在很多个servlet中加上这一个重复多次的代码(当然实际使用中,不会有那么多servlet,会利用一些手段将多个功能汇集到一个servlet中)

2.所以为了处理n多个请求的编码问题(这里只演示一个),可以使用过滤器来统一处理。

  1. package work.filter;
  2.  
  3. import java.io.IOException;
  4.  
  5. import javax.servlet.Filter;
  6. import javax.servlet.FilterChain;
  7. import javax.servlet.FilterConfig;
  8. import javax.servlet.ServletException;
  9. import javax.servlet.ServletRequest;
  10. import javax.servlet.ServletResponse;
  11. import javax.servlet.http.HttpServletRequest;
  12. import javax.servlet.http.HttpServletResponse;
  13.  
  14. public class MyFilter implements Filter {
  15.  
  16. @Override
  17. public void destroy() {
  18.  
  19. }
  20.  
  21. @Override
  22. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  23. throws IOException, ServletException {
  24. HttpServletRequest req=(HttpServletRequest)request;
  25. HttpServletResponse resp=(HttpServletResponse)response;
  26. String method = req.getMethod();
  27. if("POST".equals(method)) {
  28. request.setCharacterEncoding("utf-8");
  29. chain.doFilter(req, resp);//这一步是放行!
  30. }
  31. //简单演示起见,不对get处理,tomcat8已经不需要了
  32. }
  33.  
  34. @Override
  35. public void init(FilterConfig arg0) throws ServletException {
  36. // TODO Auto-generated method stub
  37.  
  38. }
  39.  
  40. }

JavaWeb:Listener和Filter的更多相关文章

  1. Servlet, Listener 、 Filter.

    Java Web的三大组件:Servlet, Listener . Filter. 使用Listener监听器:八大监听器: 第一组:用于监听Servlet三个域对象的创建与销毁 1. Servlet ...

  2. Listener与Filter

    一.监听器Listener javaEE的13们规范中 包括servlet技术和jsp技术 servlet规范中包括三门技术:(servlet的三大组件) servelt技术  Listener技术 ...

  3. spring boot中使用servlet、listener和filter

    spring boot中支持使用java Web三大组件(servlet.listener和filter),但是坑比较多,主要是spring boot内嵌tomcat和独立tomcat服务器有一些细节 ...

  4. Javaweb里面的filter,listener,servlet

    Filter 1Filter是什么:是过滤器简称 2Filter有什么作用:在filter中可以得到代表用户请求和响应的request.response对象,因此在编程中可以使用Decorator(装 ...

  5. JavaWeb(八):Filter和Listener

    一.Filter 1.1 概述 Filter 的基本功能是对 Servlet 容器调用 Servlet 的过程进行拦截,从而在 Servlet 进行响应处理的前后实现一些特殊的功能.在 Servlet ...

  6. JavaWeb 三大器--Listener、Filter 和Interceptor 总结

    说明:web.xml的加载顺序是:[Context-Param]->[Listener]->[Filter]->[Servlet],而同个类型之间的实际程序调用的时候的顺序是根据对应 ...

  7. 使用javaWeb的二大(Listener、Filter)组件实现分IP统计访问次数

    分析: 统计工作需要在所有资源之前都执行,那么就可以放到Filter中. 我们这个过滤器不打算做拦截操作!因为我们只是用来做统计 用什么东西来装载统计的数据.Map<String,Integer ...

  8. java-web中的Filter&Listener

    Filter过滤器 当访问服务器资源的时候,过滤器可以将i气你个球拦截下来,完成一些特殊的功能 过滤器的作用: 一般用于完成通用的操作,如验证登陆,统一的编码处理,敏感字符过滤.就是打游戏骂人,会出现 ...

  9. JavaWeb——Listener

    一.基本概念 JavaWeb里面的listener是通过观察者设计模式进行实现的.对于观察者模式,这里不做过多介绍,大概讲一下什么意思. 观察者模式又叫发布订阅模式或者监听器模式.在该模式中有两个角色 ...

随机推荐

  1. Egg中使用egg-mongoose和常用的Mongoose 方法

    Mongoose Mongoose就是一套操作MongoDB数据库的接口,而Egg中有对应的插件egg-mongoose. 安装 $ npm install egg-mongoose --save 配 ...

  2. linux中Java项目占用cpu、内存过高时的排查经历

    一.使用top命令查看占用高资源的java项目的进程ID(pid): top 二.查看该进程中的线程所占用资源的情况:top -Hp pid 三.查看该线程对应的16进制:printf %x 1112 ...

  3. Windows Azure开发之Linux虚拟机

     Windows Azure是微软的云服务集合,用来提供云在线服务所需要的操作系统与基础存储与管理的平台,是微软的云计算的核心组成组件之一.其中windows azure提供的最重要的一项服务就是 ...

  4. enumerate使用

    # enumerate读取文件import enumfor index, line in enumerate(open('C:\\Users\\CTO\\Desktop\\spider\\douban ...

  5. 滴滴工程师带你深入理解 TCP 握手分手全过程

      本文作者:饶全成,中科院计算所硕士,滴滴出行后端研发工程师. 个人主页:https://zhihu.com/people/raoquancheng   记得刚毕业找工作面试的时候,经常会被问到:你 ...

  6. vue页面参数闪一下的问题

    解决方法: 直接在外层元素加上v-cloak <div id='app' v-cloak></div>

  7. TCP/IP 笔记 - 地址解析协议

    地址解析协议(ARP)提供了一种在IPv4地址和各种网络技术使用的硬件地址之间的映射.ARP仅用于IPv4,IPv6使用邻居发现协议,它被合并入ICMPv6.地址解析是发现两个地址之间的映射关系的过程 ...

  8. MongoDB 系列文章

    MongoDB 系列文章 本文的内容是基于 MongoDB 4.0 的. 参考于 MongoDB 4.0 官方文档. 搭建 MongoDB从搭建到优化 MongoDB-副本集搭建与管理 管理 Mong ...

  9. 自己动手实现java数据结构(四)双端队列

    1.双端队列介绍 在介绍双端队列之前,我们需要先介绍队列的概念.和栈相对应,在许多算法设计中,需要一种"先进先出(First Input First Output)"的数据结构,因 ...

  10. 初学javaScript推荐工具

    对于刚开始学习js的同学,强烈推荐直接使用chrome developer mode,超级方便. 随便打开一个网页,开启开发者模式即可写js代码,不用新建html和js文件即可看到自己写的js代码的结 ...