SpringMVC拦截器和异常处理器

拦截器

基本定义

  • 拦截器(Interceptor)是一种强大的机制,允许在请求处理的不同阶段(如请求到达控制器之前、控制器处理请求之后、视图渲染之后)执行自定义逻辑。拦截器通常用于以下场景:
    • 日志记录。
    • 权限验证。
    • 请求参数预处理。
    • 性能监控等。

工作原理

  • Spring MVC 拦截器基于 HandlerInterceptor 接口实现,它定义了三个方法,分别在请求处理的不同阶段执行:

    方法名 执行时机
    preHandle 在请求到达控制器之前执行。如果返回 false,则中断请求处理。
    postHandle 在控制器处理请求之后、视图渲染之前执行。
    afterCompletion 在视图渲染之后执行,通常用于资源清理。
    一定会执行即使是报错也一样
    特性 path="/" path="/**"
    匹配范围 仅匹配根路径 / 匹配根路径 / 和所有子路径

定义拦截器

  • 要实现一个拦截器,需要实现 HandlerInterceptor 接口,并重写其方法。

  • package com.example.interceptor;
    
    import org.springframework.web.servlet.HandlerInterceptor;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class LoggingInterceptor implements HandlerInterceptor {
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                throws Exception {
            System.out.println("Before handling the request: " + request.getRequestURI());
            return true; // 继续处理请求
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                               org.springframework.web.servlet.ModelAndView modelAndView) throws Exception {
            System.out.println("After handling the request: " + request.getRequestURI());
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
                throws Exception {
            System.out.println("After rendering the view: " + request.getRequestURI());
        }
    }
    

配置拦截器

  • 可以通过 Java 配置类或 XML 配置文件来注册拦截器。

    • 配置类

      • 在配置类中实现 WebMvcConfigurer 接口,并重写 addInterceptors 方法。
    • package com.example.config;
      
      import com.example.interceptor.LoggingInterceptor;
      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 WebConfig implements WebMvcConfigurer {
      
          @Override
          public void addInterceptors(InterceptorRegistry registry) {
              // 注册拦截器
              registry.addInterceptor(new LoggingInterceptor())
                      .addPathPatterns("/**") // 拦截所有路径
                      .excludePathPatterns("/static/**"); // 排除静态资源
          }
      }
      
    • XML 配置文件

      • 在 Spring配置文件中配置拦截器。

      • <mvc:interceptors>
            <mvc:interceptor>
                <mvc:mapping path="/**"/> <!-- 拦截所有路径 -->
                <mvc:exclude-mapping path="/static/**"/> <!-- 排除静态资源 -->
                <bean class="com.example.interceptor.LoggingInterceptor"/>
            </mvc:interceptor>
        </mvc:interceptors>
        

拦截器执行顺序

  • 如果有多个拦截器,它们的执行顺序如下:

    • preHandle:按拦截器的注册顺序依次执行。
      • 按照拦截器的配置顺序依次执行。
      • 如果某个拦截器的preHandle方法返回false,则后续拦截器和处理器都不会执行,且会触发已执行拦截器的afterCompletion方法。
    • postHandle:按拦截器的注册顺序逆序执行。
    • afterCompletion:按拦截器的注册顺序逆序执行。
      • postHandle执行完毕后执行
  • 改变执行顺序

    • @Configuration
      public class WebConfig implements WebMvcConfigurer {
      
          @Override
          public void addInterceptors(InterceptorRegistry registry) {
              registry.addInterceptor(new FirstInterceptor()).order(1);
              registry.addInterceptor(new SecondInterceptor()).order(2);
              registry.addInterceptor(new ThirdInterceptor()).order(3);
          }
      }
      
    • order值越小,优先级越高,即FirstInterceptorpreHandle会先执行,postHandleafterCompletion会后执行。

异常处理器

异常处理方式:Spring MVC 提供了以下几种方式来处理异常:

  • 局部异常处理:使用 @ExceptionHandler 注解在控制器内部处理异常。
  • 全局异常处理:使用 @ControllerAdvice@RestControllerAdvice 注解定义全局异常处理器。
  • 默认异常处理:通过实现 HandlerExceptionResolver 接口自定义异常解析器。
  • 默认的 Spring MVC 异常处理:Spring MVC 默认提供了 DefaultHandlerExceptionResolverResponseStatusExceptionResolver 来处理常见异常。

局部异常处理:@ExceptionHandler

  • @ExceptionHandler 注解用于在单个控制器中处理特定的异常。它可以定义在控制器方法中,用于捕获控制器内部抛出的异常。

  • @RestController
    public class MyController {
    
        @GetMapping("/test")
        public String test() {
            throw new RuntimeException("Test exception");
        }
    
        // 处理控制器内部的 RuntimeException
        @ExceptionHandler(RuntimeException.class)
        public ResponseEntity<String> handleRuntimeException(RuntimeException ex) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error: " + ex.getMessage());
        }
    }
    
  • 只能处理当前控制器中的异常。

  • 支持多种异常类型,可以通过数组指定多个异常类,例如 @ExceptionHandler({RuntimeException.class, IOException.class})

全局异常处理:@ControllerAdvice@RestControllerAdvice

  • @ControllerAdvice@RestControllerAdvice 注解用于定义全局异常处理器,可以处理所有控制器中抛出的异常。

    • @ControllerAdvice:适用于返回视图的控制器。

    • @RestControllerAdvice:适用于返回 JSON 或 XML 数据的 REST 控制器。

    • @RestControllerAdvice
      public class GlobalExceptionHandler {
      
          // 处理全局的 RuntimeException
          @ExceptionHandler(RuntimeException.class)
          public ResponseEntity<String> handleRuntimeException(RuntimeException ex) {
              return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Global Error: " + ex.getMessage());
          }
      
          // 处理自定义异常
          @ExceptionHandler(CustomException.class)
          public ResponseEntity<String> handleCustomException(CustomException ex) {
              return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Custom Error: " + ex.getMessage());
          }
      }
      
    • 可以处理所有控制器中的异常。

    • 支持定义多个异常处理方法。

    • 可以通过 @ControllerAdvice(annotations = RestController.class) 限定只处理特定注解的控制器。

自定义异常解析器:HandlerExceptionResolver

  • 通过实现 HandlerExceptionResolver 接口,可以自定义异常处理逻辑。Spring MVC 会调用 resolveException 方法来处理异常。

  • @Component
    public class CustomExceptionResolver implements HandlerExceptionResolver {
    
        @Override
        public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
            if (ex instanceof CustomException) {
                ModelAndView mav = new ModelAndView();
                mav.addObject("error", ex.getMessage());
                mav.setViewName("error");
                return mav;
            }
            return null; // 返回 null 表示继续调用其他异常处理器
        }
    }
    
  • 可以完全控制异常处理逻辑。

  • 适用于需要复杂处理的场景。

默认的 Spring MVC 异常处理

  • Spring MVC 提供了两个默认的异常解析器:
    • DefaultHandlerExceptionResolver
      • 处理 Spring MVC 内部抛出的标准异常,例如 HttpRequestMethodNotSupportedExceptionHttpMediaTypeNotSupportedException 等。
      • 返回标准的 HTTP 状态码。
    • ResponseStatusExceptionResolver
      • 处理带有 @ResponseStatus 注解的异常。
      • 根据注解中的状态码返回 HTTP 响应。
posted @ 2025-03-18 15:30  QAQ001  阅读(106)  评论(0)    收藏  举报