1 三大组件之Filter过滤器

1.1 概念与运行原理

基础概念

Filter译为过滤器。 由于 Servlet 规范是开放的,借助于公众与开源社区的力量, Servlet 规范越来越科学,功能也越来越强大。 2000 年, Sun 公司在 Servlet2.3 规范中添加了 Filter 功能,并在 Servlet2.4 中对 Filter 进行了细节上的补充。

运行原理

当客户端向服务器端发送一个请求时,如果有对应的过滤器进行拦截,过滤器可以改变请求的内容、或者重新设置请求协议的相关信息等,然后再将请求发送给服务器端的Servlet进行处理。当Servlet对客户端做出响应时,过滤器同样可以进行拦截,将响应内容进行修改或者重新设置后,再响应给客户端浏览器。在上述过程中,客户端与服务器端并不需要知道过滤器的存在。

在一个Web应用程序中,可以部署多个过滤器进行拦截,这些过滤器组成了一个过滤器链。过滤器链中的每个过滤器负责特定的操作和任务,客户端的请求在这些过滤器之间传递,直到服务器端的Servlet。具体执行流程如下:
Filter和Listener的使用 - 图1

1.2 SpringBoot使用自定义的Filter过滤器

实现了Filter接口MyBrandFilter

  1. package com.efly.gulimall.product.filter;
  2. import javax.servlet.*;
  3. import java.io.IOException;
  4. public class MyBrandFilter implements Filter {
  5. @Override
  6. public void init(FilterConfig filterConfig) {
  7. System.out.println("init");
  8. }
  9. @Override
  10. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
  11. System.out.println("doFilter");
  12. //拦截了需要把请求释放了
  13. filterChain.doFilter(servletRequest, servletResponse);
  14. }
  15. @Override
  16. public void destroy() {
  17. }
  18. }

将上面自定义的MyBrandFilter注入到SpringIOC

  1. package com.efly.gulimall.product.config;
  2. import com.efly.gulimall.product.filter.MyBrandFilter;
  3. import org.springframework.boot.web.servlet.FilterRegistrationBean;
  4. import org.springframework.context.annotation.Bean;
  5. import org.springframework.context.annotation.Configuration;
  6. import java.util.Arrays;
  7. @Configuration
  8. public class RegistServletFilterListenerConfig {
  9. @Bean
  10. public FilterRegistrationBean myFilter() {
  11. //自定义过滤器
  12. MyBrandFilter myBrandFilter = new MyBrandFilter();
  13. FilterRegistrationBean filterRegistrationBean =
  14. new FilterRegistrationBean(myBrandFilter);
  15. //要监听的Servlet路径
  16. filterRegistrationBean.setUrlPatterns(Arrays.asList("/product/brand/*"));
  17. return filterRegistrationBean;
  18. }
  19. }

测试

  1. package com.efly.gulimall.product.controller;
  2. import com.efly.common.utils.PageUtils;
  3. import com.efly.common.utils.R;
  4. import com.efly.gulimall.product.service.BrandService;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.stereotype.Controller;
  7. import org.springframework.web.bind.annotation.RequestMapping;
  8. import javax.servlet.http.HttpServletRequest;
  9. import javax.servlet.http.HttpSession;
  10. import java.util.Map;
  11. import java.util.concurrent.ThreadPoolExecutor;
  12. /**
  13. * 品牌
  14. *
  15. * @author zhuyf
  16. * @email 946150650@qq.com
  17. * @date 2021-07-15 11:23:13
  18. */
  19. @Controller
  20. @RequestMapping("product/brand")
  21. public class BrandController {
  22. @Autowired
  23. private BrandService brandService;
  24. @Autowired
  25. private ThreadPoolExecutor executor;
  26. @RequestMapping("/list")
  27. public R list(Map<String, Object> params) throws Exception {
  28. PageUtils pageDB = brandService.queryPageFromDB(params);
  29. return R.ok().put("page", pageDB);
  30. }
  31. @RequestMapping("/setSession")
  32. public String setSession(HttpSession session, HttpServletRequest request) {
  33. System.out.println("set");
  34. StudentVO studentVO = new StudentVO();
  35. studentVO.setAge(11);
  36. //存入方式一
  37. request.getSession().setAttribute("studentVo", studentVO);
  38. //存入方式二
  39. session.setAttribute("name", "fly");
  40. return "match";
  41. }
  42. @RequestMapping("/getSession")
  43. public String getSession(HttpSession session, HttpServletRequest request) {
  44. System.out.println(session.getAttribute("fly"));
  45. System.out.println(request.getSession().getAttribute("studentVo"));
  46. return "match";
  47. }
  48. }
  49. 测试结果:
  50. 项目启动的时候,会先出发Filter.init()方法,输出init
  51. 访问product/brand/*下的任意一个接口,都会先调用Filter的doFilter()方法

1.3 Filter过滤器和Interceptor拦截器

1.3.1 概述

image.png
Filter和Listener的使用 - 图3
Filter和Listener的使用 - 图4

2 三大组件之Listener监听器

监听器就是实时监视一些事物状态的程序,我们称为监听器。目前众多的监听器中只有ServletContextListener还有一定的用处。
实现步骤

  1. 创建一个ServletContextListenerImpl类实现ServletContextListener

Filter和Listener的使用 - 图5

  1. 在web.xml文件中的配置如下

com.fly.ContextListener
  1. 这个时候,启动web工程和正常停止web工程,后台都会如下打印

Filter和Listener的使用 - 图6