JavaWeb_06_Filter&Listener

Filter&Listener

服务器端的三大组件

  • Servlet:用来处理用户请求
  • Filter:用来过滤用户请求
  • Listener:用来监听ServletContext、HttpSession、ServletRequest的生命周期和属性变化
  • 服务器端的三大组件都有以下特点:
    • 都需要运行在服务器上
    • 都需要实现某个接口
    • 都需要在web.xml中注册

Filter简介

  • Filter翻译过来叫过滤器

  • 过滤器的作用

    • 请求到达目标资源之前拦截请求
    • 放行请求
    • 响应到达浏览器之前做一些其他的操作
  • 创建Filter的HelloWorld的步骤:

    • 1)创建一个类实现Filter接口
    public class HelloFilter implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
    
        }
    
        //拦截用户请求的方法
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            System.out.println("你已经被我拦截……");
            //如果符合条件,可以放行请求
            filterChain.doFilter(servletRequest,servletResponse);
        }
    
        @Override
        public void destroy() {
    
        }
    }
    
    • 2)在web.xml中注册实现类
    <!--注册Filter-->
        <filter>
            <filter-name>HelloFilter</filter-name>
            <filter-class>com.atguigu.filter.HelloFilter</filter-class>
        </filter>
        <!--映射Filter-->
        <filter-mapping>
            <filter-name>HelloFilter</filter-name>
            <url-pattern>/index.jsp</url-pattern>
        </filter-mapping>
    
    • 3)在浏览器中访问index.jsp时则会调用HelloFilter的doFilter方法来拦截请求
     //拦截用户请求的方法
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            System.out.println("你已经被我拦截……");
        }
    
    • 4)如果满足要求,可以在doFilter方法中通过filterChain.doFilter(request, response)放行请求
    //拦截用户请求的方法
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            System.out.println("你已经被我拦截……");
            //如果符合条件,可以放行请求
            filterChain.doFilter(servletRequest,servletResponse);
        }
    

Filter的生命周期

  • 构造器
    • 服务器一启动就被调用,说明服务器一启动就创建了Filter对象
    • 在整个生命周期过程中只被调用一次,说明Filter也是单例的
  • init()方法
    • 服务器一启动就被调用,对Filter对象进行初始化
    • 在整个生命周期过程中只被调用一次
  • doFilter()方法
    • 每次发送请求都会被调用,用来拦截请求在
    • 整个生命周期过程中会被调用多次
  • destory()方法
    • 服务器关闭时被调用,用来销毁Filter对象
    • 在整个生命周期过程中只被调用一次
public class LifeFilter implements Filter {


    /*
        启动服务器时被调用,说明Filter对象一启动服务器就被创建
         在整个生命周期过程中只被调用一次,证明Filter对象也是单例的
     */
    public LifeFilter() {
        System.out.println("LifeFilter对象被创建");
    }

    /*
        启动服务器时被调用,用来初始化LifeFilter对象
        在整个生命周期过程中只被调用一次
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("LifeFilter对象被初始化");
        //filterConfig的作用
        //1.获取当前Filter的名称
        String filterName = filterConfig.getFilterName();
        System.out.println(filterName);
        //2.获取当前Filter的初始化参数
        String user = filterConfig.getInitParameter("user");
        System.out.println(user);
        //3.获取ServletContext
        ServletContext servletContext = filterConfig.getServletContext();
        System.out.println(servletContext);
    }

    /*
        向在url-pattern标签中配置的地址发送请求时被调用,用来拦截请求
        整个生命周期过程中会被调用多次
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("LifeFilter对象正在拦截请求");
    }

    /*
        关闭服务器时被调用,用来销毁对象
        整个生命周期过程中只被调用一次
     */
    @Override
    public void destroy() {
        System.out.println("LifeFilter对象被销毁");
    }
}

多个Filter的拦截顺序

  • 我们可以为同一个资源设置多个Filter,多个Filte组成一个Filter链,多个Filter的执行顺序由web.xml中的filter-mapping标签来决定,在前的先拦截,在后的后拦截;如果是通过注解的方式拦截请求,那么拦截的顺序由过滤器的名字(按A-Z的顺序)决定
<filter>
        <filter-name>RobFilter</filter-name>
        <filter-class>com.atguigu.filter.RobFilter</filter-class>
    </filter>

    <filter>
        <filter-name>RobFilter2</filter-name>
        <filter-class>com.atguigu.filter.RobFilter2</filter-class>
    </filter>
    <!--
        多个Filter的拦截顺序由filter-mapping决定,配置在前的先拦截,在后的后拦截
    -->
    <filter-mapping>
        <filter-name>RobFilter2</filter-name>
        <!--url-pattern标签可以配置多个,即一个Filter可以拦截多个地址-->
        <url-pattern>/rob.jsp</url-pattern>
        <!--
            还有通过servlet-name标签配置
            例如:<servlet-name>UserServlet</servlet-name>,向UserServlet发送的请求都会被拦截
        -->
<!--        <servlet-name></servlet-name>-->
    </filter-mapping>
    <filter-mapping>
        <filter-name>RobFilter</filter-name>
        <url-pattern>/rob.jsp</url-pattern>
    </filter-mapping>

url-pattern的配置规则

  • 精确匹配
    • 设置一个完整的路径
    • 例如:/index.jsp
      • 只有访问index.jsp时才会拦截请求
    • 我们也可以通过servlet-name标签来配置拦截的路径
      • 例如:UserServlet
        • 拦截向UserServlet发送的请求
  • 模糊匹配
    • 前缀匹配
      • 例如:/pages/*
        • 只要访问pages目录下的资源都会被拦截
    • 后缀匹配
      • 例如:*.jsp
        • 只要访问jsp页面都会被拦截
    • 注意:以下配置方式是无效的
      • /pages/*.jsp

Listener简介

  • 监听器分为三大类八种(8个接口)
    • 生命周期监听器(3个)
    • 属性变化监听器(3个)
    • session域中的属性变化监听器(2个)

生命周期监听器

  • ServletRequest的生命周期监听器

    • ServletRequestListener接口
      • 监听ServletRequest对象的创建与销毁
  • HttpSession的生命周期监听器

    • HttpSessionListener接口
      • 监听HttpSession对象的创建与销毁
  • ServletContext的生命周期监听器

    • ServletContextListener

      • 监听ServletContext对象的创建与销毁
    • 使用方式:

      • 1)创建一个类实现ServletContextListener接口
      public class MyServletContextListener implements ServletContextListener {
          //MyServletContextListener对象被创建时调用
          @Override
          public void contextInitialized(ServletContextEvent servletContextEvent) {
              System.out.println("MyServletContextListener对象被创建了");
          }
      
          //MyServletContextListener对象被销毁时调用
          @Override
          public void contextDestroyed(ServletContextEvent servletContextEvent) {
              System.out.println("MyServletContextListener对象被销毁");
          }
      }
      
      • 2)在web.xml文件中注册实现类
      <?xml version="1.0" encoding="UTF-8"?>
      <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
               version="4.0">
          <!--注册监听器-->
          <listener>
              <listener-class>com.atguigu.listener.MyServletContextListener</listener-class>
          </listener>
      </web-app>
      

属性变化监听器

  • 属性的变化指
    • 属性的添加
    • 属性的替换
    • 属性的移除
  • ServletRequest的属性变化监听器
    • ServletRequestAttributeListener接口
      • 监听request域中的属性的添加、替换、移除
  • HttpSession的属性变化监听器
    • HttpSessionAttributeListener接口
      • 监听session域中的属性的添加、替换、移除
  • ServletContext的属性变化监听器
    • ServletContextAttributeListener接口
      • 监听application域中的属性的添加、替换、移除

session域中的属性变化监听器

  • 通过以下两个接口创建的监听器不需要在web.xml中注册
  • 以下两个接口是由JavaBean来实现,然后JavaBean实例在session域中的变化将会被自动监听
  • HttpSessionBindingListene接口
    • 用来监听JavaBean实例在session域中的添加和移除
  • HttpSessionActivationListener接口
    • 用来监听Session与session域中的JavaBean实例的活化和钝化

Filter

<%--
  Created by IntelliJ IDEA.
  User: fjc02
  Date: 2020/3/2
  Time: 9:08
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>首页</title>
  </head>
  <body>
<h1>你能看见我么?</h1>
  </body>
</html>

package com.atguigu.filter;

import javax.servlet.*;
import java.io.IOException;

/**
 * @author Study hard Java's Tang
 * @create 2020-03-02 9:10
 */
public class HelloFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("你已经被我拦截");
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {

    }
}

Listener

package com.atguigu.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class MyServletContextListener implements ServletContextListener {
    //MyServletContextListener对象被创建时调用
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.println("MyServletContextListener对象被创建了");
    }

    //MyServletContextListener对象被销毁时调用
    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        System.out.println("MyServletContextListener对象被销毁");
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值