过滤器&监听器

过滤器

过滤器对请求有一个拦截的作用,当请求满足我们定义的要求的时候,可以访问目标资源,不满足要求的话,不能访问目标资源

简介

  • 过滤器主要用来过滤请求,是服务器的三大组件之一

  • 服务器三大组件:servlet、filter、listener

  • 服务器三大组件共同特点

    • 都需要在web.xml中注册或写注解
    • 都运行在服务器上

Filter入门使用

  • 使用步骤

    • 创建类实现Filter接口
    • 在web.xml中注册Filter
    • Tomcat启动的时候自动创建的实现类对象
    import javax.servlet.*;
    import java.io.IOException;
    
    
    /**
     * @author: ChengLong
     * @version: 11.0.2
     * @datetime: 2021/8/23 9:18
     */
    @WebFilter("/hello.jsp")
    public class HelloFilter implements Filter {
        // 初始化过滤器
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            System.out.println("HelloFilter==初始化了");
        }
    
        // 过滤请求的核心方法
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            System.out.println("1、请求被处理");
            //放行请求
            filterChain.doFilter(servletRequest,servletResponse);
            // 服务器给浏览器作出响应时候,执行的是filterChain.doFilter
            System.out.println("3、服务器给浏览器作出响应");
        }
    
        //过滤器销毁时调用
        @Override
        public void destroy() {
            System.out.println("HelloFilter===销毁了");
        }
    }
    
    

Filter-mapping的匹配规则

  • 精确匹配

    • 设置一个完整路径,只有对page.jsp发出请求的时候才会被拦截
      Web.xml配置:>/page.jsp
      注解配置:
@WebFilter("/page.jsp")
	- 在filter-mapping中servlet-name中设置需要拦截的serlet的名称
	<filter-mapping>
    	<filter-name>FilterUrlPattern</filter-name>
	<!--设置需要拦截的servlet的名称,往HelloServlet发出请求的时候会被拦截 -->
    	<servlet-name>HelloServlet</servlet-name>
  	</filter-mapping>
  • 模糊匹配

    • 前缀匹配:/user/* 只要访问user下的资源都会被拦截
    • 后缀匹配:*.jsp只要访问jsp文件都会被拦截
    • 不合法写法:/.jsp或者/user/.jsp

Web应用中路径问题

  • "/":绝对路径
  • “/"由浏览器解析代表:http://localhost:8080/ (主机地址)
    a标签中的href、script标签中的src、link标签中的href、重定向、表单中的action值
  • ”/“由服务器解析:由服务器解析代表:http://localhost:8080/项目名称/
    转发中的地址、url-pattnts中的地址,servletContext.realPath(“/”)中的地址

监听器

简介

  • Listener翻译过来叫监听器,是服务器端的三大组件之一,主要用来监听域对象的生命周期和属性的变化。
  • 监听器:自己创建
  • 监听的对象:ServletContext、HttpSession、ServletRequest
  • 监听的事件:生命周期和属性变化

监听器分类

  • 第一类生命周期:监听ServletContext、HttpSession、ServletRequest
  • 第二类属性变化:ServletContext、HttpSession、ServletRequest
  • 第三类:监听Session与类的关系

监听生命周期

  • ServletContext的创建与销毁

    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    import javax.servlet.annotation.WebListener;
    
    /**
     * @author: ChengLong
     * @version: 11.0.2
     * @datetime: 2021/8/23 15:16
     */
    //监听 ServletContext创建于销毁
    //@WebListener
    public class MyServletContextListener implements ServletContextListener {
        @Override
        public void contextInitialized(ServletContextEvent servletContextEvent) {
            System.out.println("ServletContext创建了");
        }
    
        @Override
        public void contextDestroyed(ServletContextEvent servletContextEvent) {
            System.out.println("ServletContext被销毁了");
        }
    }
    
    
    • 监听结果

      • tomcat启动时调用ContextInitialized方法,说明servletContext在服务器启动时被创建;
      • 服务器关闭时调用contextDestroyed方法,说明服务器关闭的时候销毁了servletContext对象
  • ServletRequest的创建与销毁

    import javax.servlet.ServletRequestEvent;
    import javax.servlet.ServletRequestListener;
    import javax.servlet.annotation.WebListener;
    
    /**
     * @author: ChengLong
     * @version: 11.0.2
     * @datetime: 2021/8/23 15:23
     */
    //@WebListener
    public class MyServletRequestListener implements ServletRequestListener {
        @Override
        public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
            System.out.println("ServletRequest==销毁了");
        }
    
        @Override
        public void requestInitialized(ServletRequestEvent servletRequestEvent) {
            System.out.println("ServletRequest==创建了");
        }
    }
    
    
    • request每次请求都会创建,请求完成就销毁
  • HttpSession的创建与销毁

    • 第一次访问jsp的时候会自动创建session对象,是因为jsp对应的java文件中的_jspService方法自动声明了该对象。
  • 第一次访问servlet需要我们手动创建session对象才可以,即:request.getSession()
    关闭服务器并且没有销毁session对象,是因为服务器关闭的时候session发生了钝化现象,即:session对象由内存被序列化到硬盘,所以没有销毁

    ```java
    import javax.servlet.annotation.WebListener;
    import javax.servlet.http.HttpSessionEvent;
    import javax.servlet.http.HttpSessionListener;
    
    /**
     * @author: ChengLong
     * @version: 11.0.2
     * @datetime: 2021/8/23 15:31
     */
    @WebListener
    public class MyHttpSessionListener implements HttpSessionListener {
        @Override
        public void sessionCreated(HttpSessionEvent httpSessionEvent) {
            System.out.println("session被创建了");
        }
    
        @Override
        public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
            System.out.println("session被销毁了");
        }
    }
    ```
    

监听属性变化

  • servletContext域中属性的变化

    import javax.servlet.ServletContextAttributeEvent;
    import javax.servlet.ServletContextAttributeListener;
    import javax.servlet.ServletContextListener;
    import javax.servlet.annotation.WebListener;
    
    /**
     * @author: ChengLong
     * @version: 11.0.2
     * @datetime: 2021/8/23 15:36
     */
    @WebListener
    public class MyServletContextAttributeListener implements ServletContextAttributeListener {
        @Override
        public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
            System.out.println("ServletContext中添加了数据");
        }
    
        @Override
        public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
            System.out.println("ServletContext中删除了数据");
        }
    
        @Override
        public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
            System.out.println("ServletContext中修改了数据");
        }
    }
    
    
  • servletRequest域中属性的变化

    import javax.servlet.ServletContext;
    import javax.servlet.ServletRequestAttributeEvent;
    import javax.servlet.ServletRequestAttributeListener;
    import javax.servlet.annotation.WebListener;
    
    //@WebListener
    public class MyServletRequestAttributeListener implements ServletRequestAttributeListener {
        @Override
        public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
            System.out.println("ServletRequest==中添加了数据");
    
        }
    
        @Override
        public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
            System.out.println("ServletRequest==中删除了数据");
        }
    
        @Override
        public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
            System.out.println("ServletRequest==中修改了数据");
        }
    }
    
    
  • HttpSession属性值变化

    import javax.servlet.annotation.WebListener;
    import javax.servlet.http.HttpSession;
    import javax.servlet.http.HttpSessionAttributeListener;
    import javax.servlet.http.HttpSessionBindingEvent;
    //@WebListener
    public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener {
        @Override
        public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
            System.out.println("HttpSession==中添加了数据");
            String name = httpSessionBindingEvent.getName();
            Object value = httpSessionBindingEvent.getValue();
            System.out.println(name+"---"+value);
        }
    
        @Override
        public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
            System.out.println("HttpSession==中删除了数据");
        }
    
        @Override
        public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
            System.out.println("HttpSession==中修改了数据");
        }
    }
    
    

监听session与类的关系

  • 监听类在session中是否存在

    • 当某个类实现了HttpSessionBindingListener接口,该类的对象如果存入到session中会调用valueBound方法,也就是对象被绑定到session中了。如果该类的对象从session移除了,会调用valueUnbound方法,也就是该类的对象从session中解绑了。
  • 监听存在session中类的活化和钝化

    • 钝化:session对象和session中保存的数据一起从内存中序列化到硬盘的过程
      服务器关闭时发视钝化
    • 活化:session对象和session中的数据一起从硬盘被反序列到内存的过程
      服务器启动的时候发生活化
    • 要保证正常的钝化和活化,session中保存的对象对应的类必须实现serializable接口
    • 当某个类实现HttpSessionActivationListener接口和serializable接口后,这个类也被保存在session中了,服务器关闭的时候发生钝化现象,这个保存在session中的类的对象被序列化到硬盘上,会调用sessionWillPassvite方法;当服务再次启动的时候,发生活化现象,这个保存在session中的类对象被 反序列化到内存上,会调用sessionDidActivate方法
    • 先访问BookServelt把Book对象存入session中,关闭服务器的时候,session会发生钝化,那么book对象中的sessionWillPassivate 方法会被调用;服务器再次重启的时候,服务器会被存储在磁盘中的session反序列化的内容,会相应的调用book对象中的 sessionDidActivate方法
posted @ 2021-08-23 22:04  Lucky_龍  阅读(37)  评论(0)    收藏  举报