目录
一、过滤器Filter。
1.1定义与规范。
1.2工作原理与范围。
1.3使用场景。
1.4 SpringBoot实现过滤器。(Filter配置2种方式)
<1>注解配置(@WebFilter、@Order、@ServletComponentScan)。
创建过滤器类。
启用 Servlet 组件扫描。
<2>配置类注册过滤器(FilterRegistrationBean对象配置)。
创建过滤器类。(无须使用第1种方式的注解)
配置过滤器。
二、拦截器Interceptor。
2.1定义与框架。
2.2工作原理与范围。
2.3使用场景。
2.4 SpringBoot实现拦截器。
<1>创建拦截器类(实现 HandlerInterceptor 接口)。
日志记录。(SLF4J、Logback)
多线程处理。(ThreadLocal)
<2>创建拦截器配置类(实现 WebMvcConfigurer 接口)。
三、全局异常捕获处理器GlobalExceptionHandler。
3.1 全局异常捕获处理器定义与实现方法。
3.2 SpringBoot实现全局异常捕获处理器。
<1>自定义响应结果封装类。(Result类)
<2>自定义全局异常捕获处理类。(GlobalExceptionHandler类)
<3>模拟产生异常的XxxController类。
一、过滤器Filter。
1.1定义与规范。
- Filter 是 Servlet 技术中的重要组件 ,遵循 Java Servlet 规范。
- 由 Servlet 容器(如 Tomcat)管理其生命周期。包括init(初始化) 、doFilter(执行过滤操作)和destroy(销毁)方法。
- 过滤器生命周期由 Servlet 容器管理。
1.2工作原理与范围。
- 过滤器的核心:拦截客户端请求和服务器响应。(请求的预处理、响应的后处理)
- 它可以对 Web 服务器管理的所有 Web 资源(如 JSP、Servlet、静态图片、静态 HTML 文件等)进行拦截。
- 在请求到达 Servlet 之前或响应离开 Servlet 之后,对请求和响应进行预处理和后处理。
1.3使用场景。
- 常用于实现 URL 级别的权限访问控制、过滤敏感词汇、压缩响应信息、设置字符编码、记录请求日志等通用功能 。
- 如:在电商网站中,可过滤用户输入中的敏感词,防止非法内容提交。或在应用入口处,对所有请求进行日志记录,便于追踪和排查问题。
1.4 SpringBoot实现过滤器。(Filter配置2种方式)
<1>注解配置(@WebFilter、@Order、@ServletComponentScan)。
创建过滤器类。
- 创建一个过滤器类(XxxFilter)实现 jakarta.servlet.Filter接口 ,并重写init()、doFilter()、destroy()方法。
- 指定过滤器顺序(补充)。若存在多个过滤器且执行顺序重要,可使用@Order注解指定顺序。数字越小优先级越高。如@Order(1) 。
package com.hyl.filter;import jakarta.servlet.*; import jakarta.servlet.annotation.WebFilter;import java.io.IOException;@WebFilter(urlPatterns = "/*", filterName = "logFilter") public class LogFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("LogFilter init,,,");}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("LogFilter doFilter,,,");long timeNow = System.currentTimeMillis();filterChain.doFilter(servletRequest,servletResponse);System.out.println("LogFilter doFilter,,,"+"耗时:"+(System.currentTimeMillis()-timeNow));}@Overridepublic void destroy() {System.out.println("LogFilter destroy,,,");} }
启用 Servlet 组件扫描。
- 在 Spring Boot 主类上添加 @ServletComponentScan 注解,扫描过滤器类(XxxFilter)。
package com.hyl;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.ServletComponentScan;@SpringBootApplication @ServletComponentScan("com.hyl.filter") public class SpringbootApplication {public static void main(String[] args) {SpringApplication.run(SpringbootApplication.class, args);}}
- 发起请求。查看过滤器执行结果。
<2>配置类注册过滤器(FilterRegistrationBean对象配置)。
创建过滤器类。(无须使用第1种方式的注解)
package com.hyl.filter;import jakarta.servlet.*; import java.io.IOException;public class LogFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("LogFilter init,,,");}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("LogFilter doFilter,,,");long timeNow = System.currentTimeMillis();filterChain.doFilter(servletRequest,servletResponse);System.out.println("LogFilter doFilter,,,"+"耗时:"+(System.currentTimeMillis()-timeNow));}@Overridepublic void destroy() {System.out.println("LogFilter destroy,,,");} }
配置过滤器。
- 创建配置类,通过 FilterRegistrationBean 注册过滤器。其中可设置过滤的 URL 路径、过滤器名称、执行顺序等。
package com.hyl.config;import com.hyl.filter.LogFilter; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;/*** 过滤器配置类:用于注册和配置自定义过滤器*/ @Configuration public class FilterConfig {@Bean // 声明将此方法的返回值作为Spring容器中的Bean管理public FilterRegistrationBean<LogFilter> logFilterRegistration(){FilterRegistrationBean<LogFilter> registration = new FilterRegistrationBean<>(); // 创建过滤器注册Bean实例(用于配置过滤器的属性registration.setFilter(new LogFilter()); // 设置要注册的过滤器实例registration.setBeanName("logFilter"); // 设置过滤器在Spring容器中的Bean名称registration.setOrder(1); // 设置过滤器的执行顺序return registration;} }
- 发起请求。查看过滤器执行结果。
二、拦截器Interceptor。
2.1定义与框架。
- 是 Spring MVC 框架中的核心组件 ,基于 Java 动态代理和 AOP(面向切面编程)实现,由 Spring 容器管理。
- 拦截器生命周期由 Spring 容器管理。
2.2工作原理与范围。
- 工作在 Spring 的 DispatcherServlet 和具体的 Controller 之间。
- 当请求到达时,DispatcherServlet 根据配置的拦截器链对请求进行预处理,再转发到相应 Controller;响应返回时,也会经过拦截器链。
- 可在请求到达 Controller 之前、Controller 方法执行之后以及请求完成后进行拦截处理。
2.3使用场景。
- 主要用于实现跨切面逻辑,如日志记录、性能统计、安全控制(如权限验证,判断用户是否有权限访问特定资源)、事务处理、返回值处理等。
- 如在某后台管理系统中,使用拦截器检查用户是否登录且具备操作权限(JWT令牌)。或在每次业务方法调用前后记录时间,统计方法执行性能。
- 过滤器适用于所有 Java Web 项目;拦截器仅适用于基于 Spring MVC 的项目。
2.4 SpringBoot实现拦截器。
<1>创建拦截器类(实现 HandlerInterceptor 接口)。
日志记录。(SLF4J、Logback)
- 使用 SLF4J(Simple Logging Facade for Java)作为日志门面,结合 Logback 作为具体的日志实现。通过 LoggerFactory.getLogger(LogInterceptor.class) 获取日志记录器。
多线程处理。(ThreadLocal)
- 使用 ThreadLocal 来存储与当前线程相关的请求时间记录 。它为每个线程提供单独的变量副本,避免多线程环境下数据错乱,保证每个线程操作的是自己的请求时间记录。最后在 afterCompletion() 方法中调用 remove() 方法及时清除数据,防止内存泄漏。
package com.hyl.interceptor;import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;import java.util.HashMap; import java.util.Map;/*** 自定义拦截器:记录请求耗时和路径*/ public class LogInterceptor implements HandlerInterceptor {private static final Logger logger = LoggerFactory.getLogger(LogInterceptor.class);// 日志记录Logbackprivate final ThreadLocal<Map<String, Object>> requestTime = new ThreadLocal<>(); // 线程安全的请求时间记录/*** 请求处理前执行(Controller 方法调用前)*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {// 记录请求开始时间long startTime = System.currentTimeMillis();Map<String, Object> timeMap = new HashMap<>();timeMap.put("startTime", startTime);timeMap.put("requestURI", request.getRequestURI()); // 记录请求路径requestTime.set(timeMap); // 存入 ThreadLocal 避免多线程冲突return true; // 返回 true 表示继续处理请求,返回 false 则拦截请求}/*** 请求处理后执行(Controller方法调用后,视图渲染前)*/@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) {}/*** 请求完成后执行(视图渲染完成后)*/@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {// 从 ThreadLocal 中获取请求时间记录Map<String, Object> timeMap = requestTime.get();if (timeMap != null) {long endTime = System.currentTimeMillis();long duration = endTime - (Long) timeMap.get("startTime"); //总耗时String requestURI = timeMap.get("requestURI").toString();// 输出日志:请求路径、耗时logger.info("【拦截器日志】请求路径:{},耗时:{}ms", requestURI, duration);requestTime.remove(); // 清除ThreadLocal数据,避免内存泄漏}} }
<2>创建拦截器配置类(实现 WebMvcConfigurer 接口)。
package com.hyl.config;import com.hyl.interceptor.LogInterceptor; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** 拦截器配置类:注册自定义拦截器*/ @Configuration public class InterceptorConfig implements WebMvcConfigurer {/*** 注册拦截器到 Spring MVC 中,并配置拦截路径*/@Overridepublic void addInterceptors(InterceptorRegistry registry) {LogInterceptor logInterceptor = new LogInterceptor(); // 创建拦截器实例registry.addInterceptor(logInterceptor) // 添加拦截器.addPathPatterns("/**") // 拦截所有路径.excludePathPatterns("/static/**", "/favicon.ico"); // 排除静态资源和图标请求。防止干扰// 若有多个拦截器,可继续调用addInterceptor()注册// 可通过 .order(n) 设置拦截执行顺序(n越小越先执行)} }
- 发起请求。查看拦截器执行结果。
- 日志输出级别:INFO。
三、全局异常捕获处理器GlobalExceptionHandler。
3.1 全局异常捕获处理器定义与实现方法。
- 在 Spring 项目中,为统一处理异常,可创建全局异常处理类。
- 1、通过在类上使用 @ControllerAdvice 注解,使其成为全局异常处理组件。
- 2、在类中的方法上使用 @ExceptionHandler 注解并指定拦截的异常类型(如Exception.class 表示拦截所有异常)来处理对应异常。
- 3、若返回字符串或 JSON 数据,需在方法上加 @ResponseBody 注解。
3.2 SpringBoot实现全局异常捕获处理器。
<1>自定义响应结果封装类。(Result类)
package com.hyl.pojo;import lombok.Data;//封装响应结果类 @Data public class Result {private String code;private String msg;private Object data;public Result() {}public Result(String code, String msg) {this.code = code;this.msg = msg;}public Result(String code, String msg, Object data) {this.code = code;this.msg = msg;this.data = data;}//响应success(无数据返回)public static Result success(){return new Result("200","操作成功");}//响应success(无数据返回)public static Result success(String msg){return new Result("200",msg);}//响应success(有数据返回)public static Result success(Object data) {return new Result("200","操作成功",data);}//响应success(有数据返回)public static Result success(String msg,Object data) {return new Result("200",msg,data);}//响应error(无数据返回)public static Result error(){return new Result("500","操作失败");}//响应error(自定义异常信息提示)public static Result error(String code, String msg){Result result = new Result();result.setCode(code);result.setMsg(msg);return result;}}
<2>自定义全局异常捕获处理类。(GlobalExceptionHandler类)
package com.hyl.exception;import com.hyl.pojo.Result; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody;// 标识该类为全局异常处理类,会对所有@Controller注解的控制器中抛出的异常进行统一捕获处理 @ControllerAdvice public class GlobalExceptionHandler {// 获取日志记录器,用于记录异常相关信息private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class); // 日志记录器@ExceptionHandler(Exception.class) // 声明该方法用于处理所有类型为Exception及其子类的异常@ResponseBody //返回值会直接作为HTTP响应体返回给客户端public Result exceptionHandle(Exception e){System.out.println(e.getMessage());//存入日志log.info("全局异常处理器:"+e.getMessage());return Result.error("500","系统繁忙!");} }
<3>模拟产生异常的XxxController类。
package com.hyl.controller;import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;@RestController @RequestMapping("/test") public class TestController {@GetMapping("/exception")public String exception() {// 模拟空指针异常String str = null;return str.length() + "";} }
- 发起请求。查看全局异常捕获处理器执行结果。