目录
一、过滤器应用场景
二、Filter:过滤器
1. 快速入门
2. 过滤器执行流程
3. 过滤器生命周期方法
4. 过滤器配置详解
5. 过滤器链(配置多个过滤器)
三、监听器
一、过滤器应用场景
过滤器是处于客户端与服务器资源文件之间的一道过滤网,在访问资源文件之前,通过一系列的过滤器对请求进行修改、判断等,把不符合规则的请求在中途拦截或修改。也可以对响应进行过滤,拦截或修改响应.
应用场景: 判断用户是否登录、过滤器请求记录日志、身份验证、权限控制等。
什么是过滤器 拦截过滤请求
过滤器可以 减少代码冗余性问题
二、Filter:过滤器
1. 快速入门
 步骤:
        1. 定义一个类,实现接口Filter
        2. 复写方法
        3. 配置拦截路径
            1. web.xml
            2. 注解@WebFilter("/*")//访问所有资源之前,都会执行该过滤器
		public class FilterDemo1 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("filterDemo1被执行了....");
 //放行
		        filterChain.doFilter(servletRequest,servletResponse);
		
		    }
		
		    @Override
		    public void destroy() {
		
		    }
		}2. 过滤器执行流程
        (1)执行过滤器
         (2)执行放行后的资源
         (3)回来执行过滤器放行代码下边的代码
3. 过滤器生命周期方法
        (1) init:在服务器启动后,会创建Filter对象,然后调用init方法。只执行一次。用于加载资源
         (2)doFilter:每一次请求被拦截资源时,会执行。执行多次
         (3) destroy:在服务器关闭后,Filter对象被销毁。如果服务器是正常关闭,则会执行destroy方法。只执行一次。用于释放资源
4. 过滤器配置详解
        * 拦截路径配置:
             (1)具体资源路径: /index.jsp   只有访问index.jsp资源时,过滤器才会被执行
             (2)拦截目录: /user/*    访问/user下的所有资源时,过滤器都会被执行
             (3)后缀名拦截: *.jsp        访问所有后缀名为jsp资源时,过滤器都会被执行
             (4)拦截所有资源:/*        访问所有资源时,过滤器都会被执行
* 拦截方式配置:资源被访问的方式
            * 注解配置:
                 * 设置dispatcherTypes属性
                     (1)REQUEST:默认值。浏览器直接请求资源
                     (2)FORWARD:转发访问资源
                     (3)INCLUDE:包含访问资源
                     (4) ERROR:错误跳转资源
                     (5)ASYNC:异步访问资源
            * web.xml配置
                 * 设置<dispatcher></dispatcher>标签即可         
5. 过滤器链(配置多个过滤器)
        * 执行顺序:如果有两个过滤器:过滤器1和过滤器2
             (1)过滤器1
             (2)过滤器2
             (3) 资源执行
             (4) 过滤器2
             (5)过滤器1 
        * 过滤器先后顺序问题:
             (1)注解配置:按照类名的字符串比较规则比较,值小的先执行
                 * 如: AFilter 和 BFilter,AFilter就先执行了。
             (2)web.xml配置: <filter-mapping>谁定义在上边,谁先执行
过滤器1执行完毕之后再执行过滤器2
注解配置的Filter,优先级按照过滤器类名(字符串)的自然排序

使用过滤器验证会话信息
需求:使用过滤器验证用户的会话信息,判断用户是否已经登录 如果 没有登录的话 则跳转到登录页面。排查“loginServlet、RegisterServlet”
package com.mayikt.filter;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import java.io.IOException;
@WebFilter("/*")// 过滤器所有的请求
public class UserSessionFilter implements Filter {
    private String[] excludeUrls = new String[]{"/login", "/register", "/VerifycodeServlet"};
    
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 从session获取到用户的会话信息 判断用户是否登录过
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
        // 定义一个数组 哪些 请求是需要排除的
        for (int i = 0; i < excludeUrls.length; i++) {
            String excludeUrl = "/mayikt_session_war_exploded" + excludeUrls[i];
            String requestURI = httpServletRequest.getRequestURI();
            if (excludeUrl.equals(requestURI)) {
                // 放行请求
                filterChain.doFilter(httpServletRequest, httpServletResponse);
                return;
            }
        }
        // 排除请求
        HttpSession session = httpServletRequest.getSession();
        Object user = session.getAttribute("user");
        if (user == null) {
            // 当前用户没有登录或者登录会话失效
            // 重定向到登录页面
            httpServletResponse.sendRedirect("/mayikt_session_war_exploded/login");
            return;
        }
        // 用户已经登录了 正常放行请求
        filterChain.doFilter(httpServletRequest, httpServletResponse);
    }
}
获取当前上下文
request.contextPath();
三、监听器
* 概念:web的三大组件之一。
	* 事件监听机制
		* 事件	:一件事情
		* 事件源 :事件发生的地方
		* 监听器 :一个对象
		* 注册监听:将事件、事件源、监听器绑定在一起。 
                   当事件源上发生某个事件后,执行监听器代码* ServletContextListener:监听ServletContext对象的创建和销毁
	
   * 方法:
		* void contextDestroyed(ServletContextEvent sce) :ServletContext对象被销毁之前会调用该方法
		* void contextInitialized(ServletContextEvent sce) :ServletContext对象创建后会调用该方法
	* 步骤:
		1. 定义一个类,实现ServletContextListener接口
		2. 复写方法
		3. 配置
			1. web.xml
					<listener>
 					 <listener- 
                  class>cn.itcast.web.listener.ContextLoaderListener</listener-class>
	           * 指定初始化参数<context-param>
			2. 注解:
				* @WebListener1. 监听器Listener就是在application,session,request三个对象创建、销毁或者往其中添加修改删除属性时自动执行代码的功能组件。
2. Listener是Servlet的监听器,可以监听客户端的请求,服务端的操作等。
3. Listener实现了javax.servlet.ServletContextListener 接口的服务器端程序,它也是随web应用的启动而启动,只初始化一次,随web应用的停止而销毁。主要作用是:做一些初始化的内容添加工作、设置一些基本的内容、比如一些参数或者是一些固定的对象等.
  (1)ServletContext监听
ServletContextListener:用于对Servlet整个上下文进行监听;
ServletContextAttributeListener:对Servlet上下文属性的监听。
  (2)Session监听
HttpSessionListener接口:对Session的整体状态的监听;
HttpSessionAttributeListener接口:对session的属性监听。
  (3)Request监听
ServletRequestListener:用于对Request请求进行监听;
ServletRequestAttributeListener:对Request属性的监听。


















