zoukankan      html  css  js  c++  java
  • JavaWeb学习之Listener&Filter

    Listener(监听器)

    > 监听某个事件的发生,其内部机制就是接口回调

    一、接口回调

    * 需求:
    > A在执行循环,当循环到5的时候, 通知B。
    > 事先先把一个对象传递给 A , 当A 执行到5的时候,通过这个对象,来调用B中的方法。
    > 但是注意,不是直接传递B的实例,而是传递一个接口的实例过去。

    二、Web监听器

    ### 使用监听器的步骤:
    1. 定义一个类,实现接口
      如:MyServletContextListener implements ServletContextListener
    2. 注册 | 配置监听器
      配置文件路径:WebContent/WEB-INF/web.xml
    <listener>
    <listener-class>实现监听器接口的类的全名称(xx.xxx.xxxx.MyServletContextListener)</listener-class>
    </listener>
    

    ### 总共有8个 划分成三种类型

    Ⅰ、监听三个作用域创建和销毁

    作用域有:

      pageContext  --- 当前页面

      request --- httpServletRequest

      session --- httpSession

      application --- ServletContext

    1、ServletContextListener(application作用域):用于监听ServletContext的创建和销毁

      servletcontext创建: 启动服务器的时候

      servletContext销毁:关闭服务器. 从服务器移除项目

    2、ServletRequestListener(request作用域):用于监听Request的创建和销毁

      request创建:访问服务器上的任意资源都会有请求出现。

            访问 html: 会
            访问 jsp: 会
            访问 servlet : 会

      request销毁:服务器已经对这次请求作出了响应。

    3、HttpSessionListener(Session作用域):用于监听Request的创建和销毁

      session的创建:只要调用getSession

            html:不会
            jsp:会   默认调用getSession();
            servlet::会(必须在代码中调用getSession())

      session的销毁:超时(一般情况30分钟)、服务器非正常关闭

    作用:

      ServletContextListener

        1. 完成自己想要的初始化工作

        2. 执行自定义任务调度。 执行某一个任务。

      HttpSessionListener

        统计在线人数

    Ⅱ、 监听三个作用域属性状态变更

    ### 可以监听在作用域中值 添加  | 替换  | 移除的动作。

    1、servletContext --- ServletContextAttributeListener

    2、request --- ServletRequestAttributeListener

    3、session --- HttpSessionAttributeListener

    session.setAttribute("name","zhangsan");//attributeAdded方法监听

    session.setAttribute("name","lisi");//attributeReplaced方法监听

    session.removedAttribute("name");//attributeRemoved方法监听

    Ⅲ、监听httpSession里面值的状态变更

    这一类监听器不用注册

      1、HttpSessionBindingListener:监听对象与session 绑定和解除绑定 的动作

        让javaBean 实现该接口即可

    			@Override
    			public void valueBound(HttpSessionBindingEvent event) {
    				System.out.println("对象被绑定进来了");
    			}
    		
    			@Override
    			public void valueUnbound(HttpSessionBindingEvent event) {
    				System.out.println("对象被解除绑定");
    			}
    

        javaBean对象存放到session中

    session.setAttribute(javaBean对象);
    session.removedAttribute(javaBean对象);
    

      2、HttpSessionActivationListener:用于监听现在session的值 是 钝化 (序列化)还是活化 (反序列化)的动作

        钝化 (序列化):把内存中的数据 存储到硬盘上

        活化 (反序列化):把硬盘中的数据读取到内存中。

        实例:

          服务器正常关闭,会使Session钝化,服务器启动Session活化

            ①、JavaBean实现HttpSessionActivationListener和Serialzable(用于序列化和反序列化,不实现此接口就无法把硬盘数据读到存储中)

    public class Bean02 implements HttpSessionActivationListener,Serialzable{
    	private String name;
    	
    	public String getName(){
    		return name;
    	}
    	
    	public void setName(String name){
    		this.name = name;
    	}
    	
    	@Override
    	public void sessionWillPassivate(HttpSessionEvent se){
    		System.out.println("Session中的值(Bean02对象)被钝化了...")
    	}
    	
    	@Override
    	public void sessionDidActivate(HttpSessionEvent se){
    		System.out.println("Session中的值(Bean02对象)被活化了...")
    	}
    }
    

            ②、session存储JavaBean对象

    <%
    Bean02 bean = new Bean02();
    bean.setName("xiaoxiao");
    session.setAttribute("sessionkey_bean",bean);
    %>
    

            ③、获取session中的数据

    <%
    sessionkey_bean.getName()
    %>
    

    可以通过正常关闭服务器测试。

            ④、通过配置让session在一定时间内钝化

              在tomcat里面 conf/context.xml 里面配置:对所有的运行在这个服务器的项目生效

              在conf/Catalina/localhost/context.xml 配置:对 localhost生效(localhost:8080)

              在自己的web工程项目中的 META-INF/context.xml:只对当前的工程生效

              配置内容:

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

    maxIdleSwap : 1分钟不用就钝化
    directory :  钝化后的那个文件存放的目录位置。( omcatapache-tomcat-7.0.52workCatalinalocalhost项目名xxx(directory的值))

    Filter(过滤器)

      > 其实就是对客户端发出来的请求进行过滤。 浏览器发出, 然后服务器派servlet处理。  在中间就可以过滤, 其实过滤器起到的是拦截的作用

    一、使用Filter

      1、定义一个类, 实现Filter接口

    		public class FilterDemo implements Filter {
    
    			public void destroy() {
    			}
    		
    			public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    				System.out.println("来到过虑器了。。。");
    				chain.doFilter(request, response);
    			}
    		
    			public void init(FilterConfig fConfig) throws ServletException {
    			}
    		
    		}
    

      2、注册过滤器

    		  <filter>
    		    <display-name>FilterDemo</display-name>
    		    <filter-name>FilterDemo</filter-name>
    		    <filter-class>com.itheima.filter.FilterDemo</filter-class>
    		  </filter>
    		  <filter-mapping>
    		    <filter-name>FilterDemo</filter-name>
    		    <url-pattern>/*</url-pattern>
    		  </filter-mapping>
    

    二、Filter的生命周期

      * 创建:服务器启动

      * 销毁:服务器停止

    三、Filter执行顺序

      1、客户端发出请求,先经过过滤器, 如果过滤器放行,那么才能到servlet

      2、如果有多个过滤器, 那么他们会按照注册的映射顺序(<filter-mapping>的顺序)。 只要有一个过滤器不放行,那么后面排队的过滤器以及咱们的servlet都不会收到请求

    		  <filter>
    		    <display-name>FilterDemo</display-name>
    		    <filter-name>FilterDemo</filter-name>
    		    <filter-class>com.itheima.filter.FilterDemo</filter-class>
    		  </filter>
    		  <filter>
    		    <display-name>FilterDemo02</display-name>
    		    <filter-name>FilterDemo02</filter-name>
    		    <filter-class>com.itheima.filter.FilterDemo02</filter-class>
    		  </filter>
    		  <filter>
    		    <display-name>FilterDemo03</display-name>
    		    <filter-name>FilterDemo03</filter-name>
    		    <filter-class>com.itheima.filter.FilterDemo03</filter-class>
    		  </filter>
    		  <filter>
    		    <display-name>FilterDemo04</display-name>
    		    <filter-name>FilterDemo04</filter-name>
    		    <filter-class>com.itheima.filter.FilterDemo04</filter-class>
    		  </filter>
    
    		  <filter-mapping>
    		    <filter-name>FilterDemo04</filter-name>
    		    <url-pattern>/*</url-pattern>
    		  </filter-mapping>
    		  <filter-mapping>
    		    <filter-name>FilterDemo02</filter-name>
    		    <url-pattern>/*</url-pattern>
    		  </filter-mapping>
    		  <filter-mapping>
    		    <filter-name>FilterDemo03</filter-name>
    		    <url-pattern>/*</url-pattern>
    		  </filter-mapping>
    		  <filter-mapping>
    		    <filter-name>FilterDemo</filter-name>
    		    <url-pattern>/*</url-pattern>
    		  </filter-mapping>
    

    1、chain.doFilter(request, response); 放行, 让请求到达下一个目标   

    2、<url-pattern>/*</url-pattern>

      全路径匹配  以 /  开始( /LoginServlet   访问LoginServlet,执行过滤器)

      以目录匹配 以 / 开始  以 * 结束 (/demo01/*  访问demo01文件夹下的文件,执行过滤器)

      以后缀名匹配  以 * 开始 以后缀名结束(*.jsp  *.html *.do  访问具体的文件类型,执行过滤器)

    3、dispatcher 设置

    		<filter-mapping>
    			<filter-name>FilterDemo</filter-name>
    			<url-pattern>/*</url-pattern>
    			
    			<dispatcher>REQUEST</dispatcher>
    			<dispatcher>FORWARD</dispatcher>
    		</filter-mapping>
    

      REQUEST:只要是请求过来,都拦截,默认就是REQUEST

      FORWARD:只要是转发都拦截

      ERROR:页面出错发生跳转

      INCLUDE:包含页面的时候就拦截

  • 相关阅读:
    axios baseURL
    TP5 nginx 配置
    Vue
    key
    curl openssl error
    vue use bulma
    《平凡的世界》
    《听听那冷雨》余光中
    心烦意乱
    祝你19岁生日快乐
  • 原文地址:https://www.cnblogs.com/WarBlog/p/13434453.html
Copyright © 2011-2022 走看看