【javaweb】组件之Filter和Listener

笔记输出来源:拉勾教育Java就业急训营

修改时间:2021年2月2日
作者:pp_x
邮箱:[email protected]

Filter

基本概念

  • Filter本意为”过滤“的含义,是JavaWeb的三大组件之一,三大组件为:Servlet、Filter、Listener
  • 过滤器是向 Web 应用程序的请求和响应处理添加功能的 Web 服务组件。
  • 过滤器相当于浏览器与Web资源之间的一道过滤网,在访问资源之前通过一系列的过滤器对请求
    进行修改、判断以及拦截等,也可以对响应进行修改、判断以及拦截等。

工作方式

在这里插入图片描述

使用方式

  • 自定义类实现Filter接口并重写doFilter方法
public class LoginFilter implements Filter {
    
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    
    

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    
    
        // 1.实现对用户访问主页面的过滤操作,也就是只有用户登录后才能访问主页面,否则一律拦截
        // 判断session中是否已有用户名信息,若没有则进行拦截,否则放行
        HttpServletRequest httpServletRequest = (HttpServletRequest)servletRequest;
        HttpSession session = httpServletRequest.getSession();
        Object userName = session.getAttribute("userName");
        // 获取Servlet的请求路径
        String servletPath = httpServletRequest.getServletPath();
        // 若没有登录,则回到登录页面
        if (null == userName && !servletPath.contains("login")) {
    
    
            servletRequest.getRequestDispatcher("login.jsp").forward(servletRequest, servletResponse);
        } else {
    
    
            // 若已经登录,则放行
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }

    @Override
    public void destroy() {
    
    

    }
}
  • 在web.xml中配置过滤器
<filter> 
        <filter-name>LoginFilter</filter-name> 
        <filter-class>com.lagou.LoginFilter</filter-class> 
    </filter> 
    <filter-mapping> 
        <filter-name>LoginFilter</filter-name> 
        <url-pattern>/main.jsp</url-pattern> //登陆后要进入的页面
    </filter-mapping>

Filter接口

  • javax.servlet.Filter接口主要用于描述过滤器对象,可以对资源的请求和资源的响应操作进行筛选操作。
  • 常用的方法:
方法 功能
void init(FilterConfig filterConfig) 实现过滤器的初始化操作
void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) 执行过滤操作的功能
void destroy() 实现过滤器的销毁操作
  • filterChain.doFilter(servletRequest, servletResponse);:放行

FilterConfig接口

  • javax.servlet.FilterConfig接口主要用于描述过滤器的配置信息。
  • 常用方法:
方法 功能
String getFilterName() 获取过滤器的名字
String getInitParameter(String name) 获取指定的初始化参数信息
Enumeration getInitParameterNames() 获取所有的初始化操作名称
ServletContext getServletContext() 获取ServletContext对象
public void init(FilterConfig filterConfig) throws ServletException {
    
    
        System.out.println("初始化操作正在火热进行中...");
        System.out.println("获取到的过滤器名称为:" + filterConfig.getFilterName());
        String userName = filterConfig.getInitParameter("userName");
        System.out.println("获取到指定初始化参数的数值为:" + userName);  // admin
        Enumeration<String> initParameterNames = filterConfig.getInitParameterNames();
        while (initParameterNames.hasMoreElements()) {
    
    
            // userName password
            System.out.println("获取到的初始化参数名为:" + initParameterNames.nextElement());
        }
        ServletContext servletContext = filterConfig.getServletContext();
        System.out.println("获取到的上下文对象是:" + servletContext);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    
    
        System.out.println("阻拦一切不合理的访问哦!");
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
    
    
        System.out.println("销毁操作执行完毕了!");
    }
}

多个过滤器的使用

在这里插入图片描述

  • 过滤器一
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    
    
        System.out.println("这是第一道防线!");
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("第一道防线返回!");
    }
  • 过滤器二
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    
    
        System.out.println("这是第二道防线!");
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("第二道防线返回!");
    }

<filter>
        <filter-name>BFilter</filter-name>
        <filter-class>com.lagou.demo02.BFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>BFilter</filter-name>
        <url-pattern>*.avi</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>AFilter</filter-name>
        <filter-class>com.lagou.demo02.AFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>AFilter</filter-name>
        <url-pattern>*.avi</url-pattern>
    </filter-mapping>
  • 注意:根据配置文件中映射的先后顺序调用过滤器
  • 输出结果:
这是第二道防线
这是第一道防线
第一道防线返回
第二道防线返回

过滤器优点

  • 实现代码的“可插拔性”,即增加或减少某个功能模块,不会影响程序的正常执行。
  • 可以将多个相同处理逻辑的模块集中写在过滤器里面可实现重复利用、也方便代码的维护。

监听器Listener

基本概念

  • Servlet规范中定义的一种特殊的组件,用来监听Servlet容器产生的事件并进行相应的处理
  • 容器产生的事件分类如下:
    • 生命周期相关的事件。
    • 属性状态相关的事件。
    • 存值状态相关的事件。
  • 底层原理是采用接口回调的方式实现。

需要进行的配置

  <listener>
        <listener-class>com.lagou.demo03.MyRequestListener</listener-class>
    </listener>

ServletRequestListener监听器

  • 在ServletRequest创建和关闭时都会通知ServletRequestListener监听器。
  • 常用方法
    • void requestInitialized(ServletRequestEvent sre):实现ServletRequest对象的初始化
    • void requestDestroyed(ServletRequestEvent sre):实现ServletRequest对象的销毁
public class MyRequestListener implements ServletRequestListener {
    
    
    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
    
    
        System.out.println("请求销毁了...");
    }

    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {
    
    
        System.out.println("创建请求...");
    }
}

ServletRequestAttributeListener监听器

  • 向ServletRequest添加、删除或者替换一个属性的时候,将会通知ServletRequestAttributeListener监听器。
  • 常用方法:
    • void attributeAdded(ServletRequestAttributeEvent srae) :增加请求属性时触发
    • void attributeReplaced(ServletRequestAttributeEvent srae):修改属性时触发
    • void attributeRemoved(ServletRequestAttributeEvent srae):删除属性时触发
public class MyRequestAttributeListener implements ServletRequestAttributeListener {
    
    
    @Override
    public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
    
    
        System.out.println("增加了属性" + servletRequestAttributeEvent.getName());
    }

    @Override
    public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
    
    
        System.out.println("属性" + servletRequestAttributeEvent.getName() + "被删除了" );
    }

    @Override
    public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
    
    
        System.out.println("修改属性" + servletRequestAttributeEvent.getName());
    }
}

HttpSessionListener监听器

  • 当一个HttpSession刚被创建或者失效(invalidate)的时候,将会通知HttpSessionListener监听器。
    • void sessionCreated(HttpSessionEvent se):当一个HttpSession对象被创建时会调用这个方法
    • void sessionDestroyed(HttpSessionEvent se):当一个HttpSession超时或者调用HttpSession的invalidate()方法让它销毁时,将会调用这个方法

HttpSessionAttributeListener监听器

  • HttpSession中添加、删除或者替换一个属性的时候,将会通知HttpSessionAttributeListener监听器。
  • 常用方法同上
public class MySessionListener implements HttpSessionListener {
    
    
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
    
    
        System.out.println("创建了session...");
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
    
    
        System.out.println("session销毁!");
    }
}
public class MySessionAttributeListener implements HttpSessionAttributeListener {
    
    
    @Override
    public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
    
    
        System.out.println("增加了属性" + httpSessionBindingEvent.getName());
    }

    @Override
    public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
    
    
        System.out.println("属性" + httpSessionBindingEvent.getName() + "被删除!");
    }

    @Override
    public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
    
    
        System.out.println("修改属性" + httpSessionBindingEvent.getName());
    }
}

ServletContextListener监听器

  • 在ServletContext创建和关闭时都会通知ServletContextListener监听器

ServletContextAttributeListener监听器

  • 向ServletContext添加、删除或者替换一个属性的时候,将会通知ServletContextAttributesListener监听器
public class MyContextListener implements ServletContextListener {
    
    
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
    
    
        System.out.println("ServletContext对象创建了...");
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
    
    
        System.out.println("销毁ServletContext对象...");
    }
}
public class MyContextAttributeListener implements ServletContextAttributeListener {
    
    
    @Override
    public void attributeAdded(ServletContextAttributeEvent servletContextAttributeEvent) {
    
    
        System.out.println("增加了属性" + servletContextAttributeEvent.getName());
    }

    @Override
    public void attributeRemoved(ServletContextAttributeEvent servletContextAttributeEvent) {
    
    
        System.out.println("属性" + servletContextAttributeEvent.getName() + "被删除!");
    }

    @Override
    public void attributeReplaced(ServletContextAttributeEvent servletContextAttributeEvent) {
    
    
        System.out.println("修改属性" + servletContextAttributeEvent.getName());
    }
}

HttpSessionBindingListener监听器

  • HttpSession中绑定和解除绑定时,将会通知HttpSessionListener监听器
    • void valueBound(HttpSessionBindingEvent event) :有对象绑定时调用该方法
    • void valueUnbound(HttpSessionBindingEvent event):有对象解除绑定时调用该方法
public class Person implements HttpSessionBindingListener {
    
    
    private String name;
    private int age;

    public Person() {
    
    
    }

    public Person(String name, int age) {
    
    
        this.name = name;
        this.age = age;
    }

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    public int getAge() {
    
    
        return age;
    }

    public void setAge(int age) {
    
    
        this.age = age;
    }

    @Override
    public String toString() {
    
    
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public void valueBound(HttpSessionBindingEvent httpSessionBindingEvent) {
    
    
        System.out.println("对象绑定到session中了" + httpSessionBindingEvent.getName());
    }

    @Override
    public void valueUnbound(HttpSessionBindingEvent httpSessionBindingEvent) {
    
    
        System.out.println("解除绑定成功!");
    }
}

<%
    // 准备一个Person类型的对象
    Person person = new Person();
    person.setName("zhangfei");
    person.setAge(30);
    // 将对象与session对象进行绑定
    session.setAttribute("person", person);
    // 解除绑定
    session.removeAttribute("person");
%>

HttpSessionActivationListener监听器

  • 当有session数值的钝化和活化操作时,将会通知HttpSessionActivationListener监听器。
    • void sessionWillPassivate(HttpSessionEvent se):有钝化操作时调用该方法
    • void sessionDidActivate(HttpSessionEvent se):有活化操作时调用该方法
    • 活化:硬盘到内存 反序列化 会话从新接入后从硬盘读取到内存
    • 钝化:内存到硬盘 序列化 会话开启后浏览器关闭存入硬盘
public class Student implements Serializable, HttpSessionActivationListener {
    
    
    private String name;

    public Student() {
    
    
    }

    public Student(String name) {
    
    
        this.name = name;
    }

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    @Override
    public String toString() {
    
    
        return "Student{" +
                "name='" + name + '\'' +
                '}';
    }

    @Override
    public void sessionWillPassivate(HttpSessionEvent httpSessionEvent) {
    
    
        System.out.println("执行了钝化操作..." + httpSessionEvent.getSession());
    }

    @Override
    public void sessionDidActivate(HttpSessionEvent httpSessionEvent) {
    
    
        System.out.println("活化操作进行中...");
    }
}

<head>
    <title>实现session中数据的钝化和活化操作</title>
</head>
<body>
<%
    // 创建Student类型的对象
    Student student = new Student();
    student.setName("zhangfei");
    // 将数据放入到session中
    session.setAttribute("student", student);
%>

</body>
  • context.xml
<Manager className="org.apache.catalina.session.PersistentManager" saveOnRestart="true">
 <!-- 配置文件存放的路径信息,可以自由指定 --> 
 <Store className="org.apache.catalina.session.FileStore" directory="C:\session"/>
  </Manager>

猜你喜欢

转载自blog.csdn.net/weixin_46303867/article/details/113528628
今日推荐