面试题:Spring 中的 @ExceptionHandler 注解的作用是什么?

@ExceptionHandler 是 Spring 框架中的一个注解,用于处理 Controller 方法中抛出的异常。它允许开发者在 Controller 内部定义异常处理方法,从而集中处理特定类型的异常,并返回自定义的错误响应。


作用

  1. 异常处理:捕获并处理 Controller 方法中抛出的异常。
  2. 自定义错误响应:根据异常类型返回自定义的 HTTP 状态码、错误信息或响应体。
  3. 代码解耦:将异常处理逻辑从业务逻辑中分离出来,提高代码的可读性和可维护性。

使用场景

  • 统一异常处理:在 Controller 内部集中处理特定类型的异常。
  • 自定义错误响应:返回自定义的错误信息或格式(如 JSON)。
  • 日志记录:在异常处理方法中记录日志,便于问题排查。

使用方法

@ExceptionHandler 通常用在 Controller 类中的方法上,用于处理当前 Controller 中抛出的异常。它可以处理指定的异常类型或其子类。

示例

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
public class MyController {

    @GetMapping("/resource/{id}")
    public String getResource(@PathVariable String id) {
        if (!"123".equals(id)) {
            throw new ResourceNotFoundException("Resource not found"); // 抛出异常
        }
        return "Resource found";
    }

    @ExceptionHandler(ResourceNotFoundException.class) // 处理 ResourceNotFoundException
    public ResponseEntity<String> handleResourceNotFoundException(ResourceNotFoundException ex) {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage()); // 返回 404 和错误信息
    }
}

在这个例子中:

  • getResource 方法抛出 ResourceNotFoundException 时,handleResourceNotFoundException 方法会被调用,并返回 HTTP 状态码 404 Not Found 和错误信息。

常用特性

  1. 处理多种异常:一个方法可以处理多种异常类型。
   @ExceptionHandler({ResourceNotFoundException.class, IllegalArgumentException.class})
   public ResponseEntity<String> handleExceptions(Exception ex) {
       return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ex.getMessage());
   }
  1. 返回自定义响应体:可以返回复杂的响应体(如 JSON)。
   @ExceptionHandler(ResourceNotFoundException.class)
   public ResponseEntity<ErrorResponse> handleResourceNotFoundException(ResourceNotFoundException ex) {
       ErrorResponse errorResponse = new ErrorResponse("NOT_FOUND", ex.getMessage());
       return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorResponse);
   }
  1. 访问请求和响应对象:可以通过方法参数访问 HttpServletRequestHttpServletResponse
   @ExceptionHandler(Exception.class)
   public ResponseEntity<String> handleException(Exception ex, HttpServletRequest request) {
       return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
               .body("Error occurred at " + request.getRequestURI() + ": " + ex.getMessage());
   }

@ControllerAdvice 结合使用

@ExceptionHandler 通常与 @ControllerAdvice 结合使用,以实现全局异常处理@ControllerAdvice 可以将异常处理逻辑集中到一个类中,供所有 Controller 共享。

示例:全局异常处理

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity<String> handleResourceNotFoundException(ResourceNotFoundException ex) {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleException(Exception ex) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Internal server error");
    }
}

在这个例子中:

  • GlobalExceptionHandler 类会处理所有 Controller 中抛出的 ResourceNotFoundException 和其他异常。
  • 通过 @ControllerAdvice,异常处理逻辑可以被多个 Controller 共享,避免重复代码。

注意事项

  1. 优先级:Controller 内部的 @ExceptionHandler 方法优先级高于 @ControllerAdvice 中的方法。
  2. 异常匹配规则@ExceptionHandler 会匹配指定异常类型及其子类。
  3. 返回值类型@ExceptionHandler 方法的返回值类型可以是 ResponseEntityString(视图名称)、ModelAndView 等。
  4. 日志记录:建议在异常处理方法中记录日志,便于问题排查。

总结

  • @ExceptionHandler 用于处理 Controller 方法中抛出的异常,支持自定义错误响应。
  • 它可以与 @ControllerAdvice 结合使用,实现全局异常处理。
  • 通过集中处理异常,可以提高代码的可读性、可维护性和一致性。

合理使用 @ExceptionHandler 可以显著提升应用的异常处理能力,同时提供清晰的错误响应语义。

THE END
点赞7 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容