SpringBoot之Filter和Listener 简单运用

目录

  • 1.引入pom依赖
  • 2.配置启动类
  • 3.Filter 的使用
    • 3.1过滤器创建
    • 3.2Filter 过滤器测试
  • 4.Listener 的使用
    • 4.1.1 监听 ServletContext对象
    • 4.1.2 监听 ServletContext对象测试
    • 4.2.1 监听 HttpSession对象
    • 4.2.2 监听 HttpSession对象测试
    • 4.3.1 监听 ServletRequest对象
    • 4.3.2 监听 ServletRequest对象测试
  • 链接:[SpringBoot之Filter和Listener 简单运用 源代码下载地址](https://download.csdn.net/download/JAVA_MHH/85083787)

1.引入pom依赖


    
    
    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.3.2.RELEASEversion>
    parent>

    <dependencies>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        
        <dependency>
            <groupId>cn.hutoolgroupId>
            <artifactId>hutool-jsonartifactId>
            <version>4.1.21version>
        dependency>
        
        <dependency>
            <groupId>org.apache.commonsgroupId>
            <artifactId>commons-lang3artifactId>
        dependency>
    dependencies>




2.配置启动类

  • @ServletComponentScan():
                   Servlet可以直接通过@WebServlet注解自动注册
                   Filter可以直接通过@WebFilter注解自动注册
                   Listener可以直接通过@WebListener 注解自动注册
import com.it.mhh.filter.MyFilter;
import com.it.mhh.listener.MyHttpSessionListener;
import com.it.mhh.listener.MyServletContextListener;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

/**
 * @创建人: Mhh
 * @创建时间: 2022/3/25
 * @描述: 监听器和和过滤器启动类
 */
//在启动类上添加@ServletComponentScan
//Servlet可以直接通过@WebServlet注解自动注册
//Filter可以直接通过@WebFilter注解自动注册
//Listener可以直接通过@WebListener 注解自动注册
@ServletComponentScan
@SpringBootApplication
public class FilterAndListenerApplication {

    public static void main(String[] args) {
        SpringApplication.run(FilterAndListenerApplication.class,args);
    }
}



3.Filter 的使用


3.1过滤器创建

  • @WebFilter():
                value[] 与urlPatterns[]属性一致: 表示过滤的路径
                            /*:表示过滤所有
                            *.html:表示只过滤html的文件
                            /app/* :表示过滤有app路径的所有文件
                            ...
  • dispatcherTypes[] : 资源被访问的方式(意思是什么时候过滤器奏效)
            FORWARD: 转发访问资源(配置此方法 只有转发的资源才会被拦截)
            INCLUDE: 包含访问资源截)
            REQUEST: 默认值。浏览器直接请求资源截)
            ASYNC: 异步访问资源
            ERROR: 错误跳转资源
  • init方法:在服务器启动后,会创建Filter对象,然后调用init方法(只执行一次)
  • doFilter方法:每一次请求被拦截资源时会执行
                          首先执行过滤器——>执行放行后的资源——>回来执行放行代码下的代码
                          如果没有放行 就不再执行后面代码.
  • destroy方法: 在服务器关闭后,Filter对象被销毁。如果服务器是正常关闭,则会执行destroy方法(只执行一次)
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;

/**
 * @创建人: Mhh
 * @创建时间: 2022/3/25
 * @描述: 过滤器
 */

//urlPatterns[]:拦截路径方式;
/* dispatcherTypes[] : 资源被访问的方式
 *   FORWARD: 转发访问资源(配置此方法 只有转发的资源才会被拦截)
 *   INCLUDE: 包含访问资源
 *   REQUEST: 默认值。浏览器直接请求资源
 *   ASYNC:   异步访问资源
 *   ERROR:   错误跳转资源
 *
 */
@WebFilter(urlPatterns = "/*") //value[] 与urlPatterns[]属性一致
public class MyFilter implements Filter {

    //用于加载资源
    //在服务器启动后,会创建Filter对象,然后调用init方法(只执行一次)
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.err.println(filterConfig.getFilterName());
        System.err.println(filterConfig.getInitParameterNames());
//        System.err.println(filterConfig.getInitParameterNames().nextElement());
        System.err.println(filterConfig.getServletContext().getClassLoader());
    }

    //每一次请求被拦截资源时会执行
    //首先执行过滤器——>执行放行后的资源——>回来执行放行代码下的代码
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        //获得请求头上的入参参数
        Map<String, String[]> parameterMap = request.getParameterMap();
        System.err.println(parameterMap);

        //使用动态代理对 servletRequest 对象请求消息增强
        ServletRequest servletRequestPoxy = (ServletRequest) Proxy.newProxyInstance(servletRequest.getClass().getClassLoader(), servletRequest.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //判断 方法名==getParameter
                if ("getParameter" == method.getName().intern()) {
                    //执行
                    Object o = method.invoke(servletRequest, args);
                    if (o instanceof String) {
                        String invoke = (String) o;
                        //判断值是否是 mhh
                        if (invoke.intern() == "mhh") {
                            //是的话 把mhh改为proxy_new_mhh并返回
                            return "proxy_new_mhh";
                        }
                    }
                }
                //直接返回实际数据
                return method.invoke(servletRequest, args);
            }
        });
        System.err.println("请求资源执行前代码操作");
        filterChain.doFilter(servletRequestPoxy, servletResponse);//放行
        //对 servletResponse 对象 相应消息增强
        System.err.println("请求资源执行完后代码操作");
    }

    //用于释放资源
    //在服务器关闭后,Filter对象被销毁。如果服务器是正常关闭,则会执行destroy方法(只执行一次)
    @Override
    public void destroy() {
        System.err.println("过滤器销毁");
    }
}



3.2Filter 过滤器测试

  • 过滤器中doFilter方法中才是真正自己要做的操作SpringBoot之Filter和Listener 简单运用_第1张图片SpringBoot之Filter和Listener 简单运用_第2张图片
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;

/**
 * @创建人: Mhh
 * @创建时间: 2022/3/26
 * @描述: 测试过滤器业务层
 */
@RestController
@RequestMapping("filter")
public class FilterController {

    @RequestMapping("get")
    public String get(HttpServletRequest httpServletRequest) {
        System.err.println("进入->: " + httpServletRequest.getRequestURI());
        return httpServletRequest.getParameter("name");
    }
}


4.Listener 的使用


4.1.1 监听 ServletContext对象

  • @WebListener : 启动监听(必须在启动类上加@ServletComponentScan)
  • ServletContextListener : 接口用于监听 ServletContext 对象的创建和销毁事件。
  • ServletContextAttributeListener : 接口用于监听ServletContext 新增 删除 替换属性
  • contextInitialized方法 : 当 ServletContext 对象被创建时,调用接口中的方法:
  • contextDestroyed方法 : 当 ServletContext 对象被销毁时,调用接口中的方法:
  • attributeAdded方法 : 当新增被监听对象中的一个属性时,web 容器调用事件监听器的这个方法
  • attributeRemoved方法 : 当删除被监听对象中的一个属性时,web 容器调用事件监听器的这个方法
  • attributeReplaced方法 : 当监听器的域对象中的某个属性被替换时,web容器调用事件监听器的这个方法
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import javax.servlet.*;
import javax.servlet.annotation.WebListener;
import java.util.TimerTask;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @创建人: Mhh
 * @创建时间: 2022/4/2
 * @描述: ServletContextListener 接口用于监听 ServletContext 对象的创建和销毁事件。
 *		  ServletContextAttributeListener接口用于监听ServletContext 新增 删除 替换属性
 */

/*ServletContextListener域对象何时创建和销毁:
        创建:服务器启动时,针对每一个web应用创建Servletcontext
        销毁:服务器关闭前,先关闭代表每一个web应用的ServletContext
*/
@WebListener
public class MyServletContextListener implements ServletContextListener, ServletContextAttributeListener {

    //当 ServletContext 对象被创建时,调用接口中的方法:
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.err.println("监听ServletContext对象创建了...");
        // 获得事件源
        ServletContext servletContext = sce.getServletContext();
        // 向ServletContext 中保存数据
            servletContext.setAttribute("age",12);
        final int[] i = {0};
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                System.err.println(i[0]++);
            }
        };
        // 通过制定的参数创建一个线程池执行器
/*
		corePoolSize   即使它们处于空闲状态也要保留在池中的线程数
		threadFactory  执行程序创建新线程时要使用的工厂
*/
// 启动定时器
        ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(2,
                new BasicThreadFactory.Builder().daemon(true).build());

/*
            command 	要执行的任务
            initialDelay 	延迟首次执行的时间
            delay 	从终止执行到开始执行之间的延迟
            unit	initialDelay和delay参数的时间单位
*/
        executorService.scheduleWithFixedDelay(task, 0, 1, TimeUnit.SECONDS);
        try {
            Thread.sleep(3000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //定时停止
        executorService.shutdown();


    }

    //当 ServletContext 对象被销毁时,调用接口中的方法:
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.err.println("监听ServletContext对象销毁了...");
    }



    /*
    * 当向被监听器对象中增加一个属性时,web容器就调用事件监听器的 attributeAdded 方法进行相应,
    * 这个方法接受一个事件类型的参数,监听器可以通过这个参数来获得正在增加属性的域对象和被保存到域中的属性对象
    * */
    @Override
    public void attributeAdded(ServletContextAttributeEvent scae) {
        System.err.println("ServletContext新增属性--> "+scae.getName()+": "+scae.getValue());
    }

    //当删除被监听对象中的一个属性时,web 容器调用事件监听器的这个方法
    @Override
    public void attributeRemoved(ServletContextAttributeEvent scae) {
        System.err.println("ServletContext删除属性--> "+scae.getName()+": "+scae.getValue());

    }

    //当监听器的域对象中的某个属性被替换时,web容器调用事件监听器的这个方法
    @Override
    public void attributeReplaced(ServletContextAttributeEvent scae) {
        System.err.println("ServletContext替换属性--> "+scae.getName()+": "+scae.getValue());

    }
}


4.1.2 监听 ServletContext对象测试

  • ServletContext对象的生成和销毁 以及属性的变化 都会执行相应的方法SpringBoot之Filter和Listener 简单运用_第3张图片
    SpringBoot之Filter和Listener 简单运用_第4张图片
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

/**
 * @创建人: Mhh
 * @创建时间: 2022/4/6
 * @描述: 测试ServletContext 业务层
 */
@RestController
@RequestMapping("servletContext")
public class MyServletContextListenerController {

    @RequestMapping("/get")
    public String get(HttpServletRequest httpServletRequest) {
        //获取 ServletContext
        ServletContext servletContext = httpServletRequest.getServletContext();
        //获取在监听器赋的值
        System.err.println("获取在监听器初始化赋的value--> " + servletContext.getAttribute("age"));
        //赋值属性
        servletContext.setAttribute("name", "mhh");
        //替换属性
        servletContext.setAttribute("name", "孟浩浩");
        //删除属性
        servletContext.removeAttribute("name");
        //返回
        return "ServletContext测试";
    }
}



4.2.1 监听 HttpSession对象

  • @WebListener : 启动监听(必须在启动类上加@ServletComponentScan)
  • HttpSessionListener接口 : 用于监听HttpSession的创建和销毁
  • HttpSessionAttributeListener接口 : 用于监听HttpSession 新增 删除 替换属性
  • sessionCreated方法 : 创建一个Session时,接口中的该方法将会被调用
  • sessionDestroyed方法 : 销毁一个Session时,接口中的该方法将会被调用
  • attributeAdded方法 : 当Session中添加属性时 调用该方法
  • attributeRemoved方法 : 当Session中删除属性时 调用该方法
  • attributeReplaced方法 : 当Session中替换属性时 调用该方法

import javax.servlet.annotation.WebListener;
import javax.servlet.http.*;

/**
 * @创建人: Mhh
 * @创建时间: 2022/4/2
 * @描述: HttpSessionListener接口用于监听HttpSession的创建和销毁
 * 		 HttpSessionAttributeListener接口用于监听ServletContext 新增 删除 替换属性	
 */

/*
Session域对象创建和销毁:
        创建:浏览器访问服务器时,服务器为每个浏览器创建不同的 session 对象,服务器创建session
        销毁:如果用户的session的30分钟没有使用,session就会过期,我们在Tomcat的web.xml里面也可以配置session过期时间。
*/
@WebListener
public class MyHttpSessionListener implements HttpSessionListener, HttpSessionAttributeListener {

    //创建一个Session时,接口中的该方法将会被调用:
    @Override
    public void sessionCreated(HttpSessionEvent se) {
        // 通过事件对象获得session 的id
        System.out.println("session被创建了");
        HttpSession session = se.getSession();
        System.out.println("id:" + session.getId());
    }

    //销毁一个Session时,接口中的该方法将会被调用:
    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        System.out.println("session被销毁了");
        HttpSession session = se.getSession();
        System.out.println("id:" + session.getId());
    }

    //当Session中添加属性时 调用该方法
    @Override
    public void attributeAdded(HttpSessionBindingEvent se) {
        System.err.println("Session是->:"+se.getSession()+" Session新增属性--> "+se.getName()+": "+se.getValue());

    }

    //当Session中删除属性时 调用该方法
    @Override
    public void attributeRemoved(HttpSessionBindingEvent se) {
        System.err.println("Session是->:"+se.getSession()+" Session删除属性--> "+se.getName()+": "+se.getValue());

    }

    //当Session中替换属性时 调用该方法
    @Override
    public void attributeReplaced(HttpSessionBindingEvent se) {
        System.err.println("Session是->:"+se.getSession()+" Session替换属性--> "+se.getName()+": "+se.getValue());

    }
}



4.2.2 监听 HttpSession对象测试

  • HttpSession对象的生成和销毁 以及属性的变化 都会执行相应的方法SpringBoot之Filter和Listener 简单运用_第5张图片
    SpringBoot之Filter和Listener 简单运用_第6张图片

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**
 * @创建人: Mhh
 * @创建时间: 2022/4/6
 * @描述: 测试Session 业务层
 */
@RestController
@RequestMapping("session")
public class MySessionListenerController {

    @RequestMapping("/get")
    public String get(HttpServletRequest httpServletRequest) {
        //获取 Session(这里也是创建session的地方)
        HttpSession session = httpServletRequest.getSession();
        //赋值属性
        session.setAttribute("name", "mhh");
        //替换属性
        session.setAttribute("name", "孟浩浩");
        //删除属性
        session.removeAttribute("name");
        //返回
        return "Session测试";
    }
}



4.3.1 监听 ServletRequest对象

  • @WebListener : 启动监听(必须在启动类上加@ServletComponentScan)
  • ServletRequestListener : 接口用于监听ServletRequest 对象的创建和销毁
  • ServletRequestAttributeListener : 接口用于监听ServletRequest 新增 删除 替换属性
  • requestDestroyed方法 : ServletRequest对象被创建时,监听器的requestInitialized方法将会被调用。
  • requestInitialized方法 : ServletRequest对象被销毁时,监听器的requestDestroyed方法将会被调用。
  • attributeAdded方法 : 当新增被监听对象中的一个属性时,web 容器调用事件监听器的这个方法
  • attributeRemoved方法 : 当删除被监听对象中的一个属性时,web 容器调用事件监听器的这个方法
  • attributeReplaced方法 : 当替换被监听对象中的一个属性时,web 容器调用事件监听器的这个方法
import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;

/**
 * @创建人: Mhh
 * @创建时间: 2022/4/6
 * @描述: ServletRequestListener 接口用于监听ServletRequest 对象的创建和销毁
 *          ServletRequestAttributeListener接口用于监听ServletRequest 新增 删除 替换属性
 */

/*
ServletRequest域对象创建和销毁的时机:
        创建:用户每一次访问,都会创建一个reqeust
        销毁:当前访问结束,request对象就会销毁
        这个监听器最需要注意的:
        使用forward ---- request创建销毁一次 (因为转发本质是一次请求)
        使用sendRedirect ---- request创建销毁两次 (因为重定向本质是两次请求)
*/

@WebListener
public class MyServletRequestListener implements ServletRequestListener, ServletRequestAttributeListener {

    //ServletRequest对象被创建时,监听器的requestInitialized方法将会被调用。
    @Override
    public void requestDestroyed(ServletRequestEvent sre) {
        System.out.println("ServletRequest对象被创建");
    }

    //ServletRequest对象被销毁时,监听器的requestDestroyed方法将会被调用。
    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        System.out.println("ServletRequest对象被销毁");
    }


    //当新增被监听对象中的一个属性时,web 容器调用事件监听器的这个方法
    @Override
    public void attributeAdded(ServletRequestAttributeEvent srae) {
        System.err.println("ServletRequest新增属性--> "+srae.getName()+": "+srae.getValue());
    }

    //当删除被监听对象中的一个属性时,web 容器调用事件监听器的这个方法
    @Override
    public void attributeRemoved(ServletRequestAttributeEvent srae) {
        System.err.println("ServletRequest删除属性--> "+srae.getName()+": "+srae.getValue());
    }

    //当替换被监听对象中的一个属性时,web 容器调用事件监听器的这个方法
    @Override
    public void attributeReplaced(ServletRequestAttributeEvent srae) {
        System.err.println("ServletRequest替换属性--> "+srae.getName()+": "+srae.getValue());
    }
}


4.3.2 监听 ServletRequest对象测试

  • servletRequest对象的生成和销毁 以及属性的变化 都会执行相应的方法SpringBoot之Filter和Listener 简单运用_第7张图片
    SpringBoot之Filter和Listener 简单运用_第8张图片
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;

/**
 * @创建人: Mhh
 * @创建时间: 2022/4/6
 * @描述: 测试ServletRequest 业务层
 */
@RestController
@RequestMapping("servletRequest")
public class MyServletRequestListenerController {


    @RequestMapping("/get")
    public String get(HttpServletRequest httpServletRequest) {
        //赋值属性
        httpServletRequest.setAttribute("name", "mhh");
        //替换属性
        httpServletRequest.setAttribute("name","孟浩浩");
        //删除属性
        httpServletRequest.removeAttribute("name");
        //反参
        return "ServletRequest 测试";
    }
}








链接:SpringBoot之Filter和Listener 简单运用 源代码下载地址

你可能感兴趣的:(SpringBoot,java,spring,boot,后端)