学会SpringBoot全局异常处理三种方式,轻松处理异常

文摘   2024-12-15 22:01   江苏  

在开发 SpringBoot Web 应用的过程中,异常处理就像给程序穿了一件盔甲,能让它在面对各种“意外”时稳如泰山。如果没有良好的异常处理机制,你的应用可能会像一个没有刹车的车,下坡的时候就只能听天由命了。本篇文章将带你轻松掌握 SpringBoot 全局异常处理的三种方式,助你从容应对开发中的各种“异常风暴”。

什么是全局异常处理?

简单来说,全局异常处理就是在应用发生错误时,统一处理这些错误,而不需要在每一个地方都写重复的代码去捕获和处理异常。就像一个万能的“保安”,只要程序“闯祸”了,它就能快速出手帮忙解决问题。

SpringBoot 提供了三种常用的全局异常处理方式:

  1. 使用@ControllerAdvice 注解。
  2. 使用@ExceptionHandler 注解。
  3. 实现HandlerExceptionResolver 接口。

下面我们逐一来看这三种方式,并配上详细的代码示例和解释。


使用@ControllerAdvice 注解

@ControllerAdvice 是一个 Spring 提供的注解,用来定义全局异常处理器。它的作用范围是所有的控制器,一次定义,处处生效。就像一个全局的“急救中心”,任何地方出问题,它都能接到报警。

示例代码

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineimport org.springframework.http.HttpStatus;import org.springframework.http.ResponseEntity;import org.springframework.web.bind.annotation.ControllerAdvice;import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvicepublic class GlobalExceptionHandler {
    @ExceptionHandler(Exception.class)    public ResponseEntity<String> handleException(Exception e) {        return ResponseEntity                .status(HttpStatus.INTERNAL_SERVER_ERROR)                .body("Oops! Something went wrong: " + e.getMessage());    }}

代码解析

  1. @ControllerAdvice:定义了一个全局异常处理类,所有控制器中的异常都会由它处理。
  2. @ExceptionHandler(Exception.class):指定要处理的异常类型为Exception,也就是所有未被捕获的通用异常。
  3. 返回值:通过ResponseEntity 返回自定义的 HTTP 状态码(500)和错误信息。

实际效果

  • 如果你的应用中某个地方抛出了一个Exception(如数据库连接失败),用户会收到一个 500 状态码和一个友好的提示信息,而不是看到一堆让人摸不着头脑的堆栈信息。

使用@ExceptionHandler 注解

@ExceptionHandler 注解可以直接写在控制器中,用于处理该控制器内部的异常。有点像“分区管理”,每个控制器都可以有自己的异常处理逻辑。

示例代码

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineimport org.springframework.beans.factory.annotation.Autowired;import org.springframework.http.HttpStatus;import org.springframework.http.ResponseEntity;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RestController;
@RestControllerpublic class UserController {
    @Autowired    private UserService userService;
    @ExceptionHandler(UserNotFoundException.class)    public ResponseEntity<String> handleUserNotFoundException(UserNotFoundException e) {        return ResponseEntity                .status(HttpStatus.NOT_FOUND)                .body("User error: " + e.getMessage());    }
    @GetMapping("/users/{id}")    public ResponseEntity<User> getUser(@PathVariable Long id) {        User user = userService.getUserById(id);        if (user == null) {            throw new UserNotFoundException("User with ID " + id + " not found");        }        return ResponseEntity.ok(user);    }}

代码解析

  1. @ExceptionHandler(UserNotFoundException.class):捕获UserNotFoundException 类型的异常,并返回一个自定义的 404 错误信息。
  2. getUser 方法:当用户 ID 不存在时,手动抛出一个UserNotFoundException
  3. 返回值:通过ResponseEntity 返回 404 状态码和详细的错误描述。

实际效果

  • 当用户访问/users/{id} 接口,而该用户 ID 不存在时,API 会返回 404 状态码和友好的错误信息:“User with ID X not found”。

实现HandlerExceptionResolver 接口

如果你需要更灵活的异常处理,比如返回自定义的页面,或者根据不同的异常类型执行不同的逻辑,可以通过实现HandlerExceptionResolver 接口来实现。

示例代码

ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineimport org.springframework.web.servlet.HandlerExceptionResolver;import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;
public class GlobalExceptionHandler implements HandlerExceptionResolver {
    @Override    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {        ModelAndView mav = new ModelAndView();        mav.addObject("error", ex.getMessage());        mav.setViewName("error"); // 指向 error.html 页面        return mav;    }}

代码解析

  1. 实现HandlerExceptionResolver 接口:通过重写resolveException 方法来自定义异常处理逻辑。
  2. ModelAndView:返回一个包含错误信息的视图(如error.html)。
  3. 灵活性:可以根据异常类型动态返回不同的页面或数据。

实际效果

  • 当某个地方抛出异常时,用户会被引导到一个定制的错误页面,而不是看到默认的错误提示。

温馨提示

  • 不要忽视小异常:一些看似无关紧要的异常(比如空指针异常)可能会导致整个程序崩溃,所以一定要养成良好的异常处理习惯。
  • 优先级问题:如果同时使用了@ControllerAdvice 和@ExceptionHandler,局部的@ExceptionHandler 会优先执行。
  • 日志记录:在处理异常时,别忘了记录日志,这样可以方便后续排查问题。

总结

本文介绍了 SpringBoot 中三种全局异常处理方式:

  1. @ControllerAdvice:适用于全局统一的异常处理。
  2. @ExceptionHandler:适用于控制器内部的局部异常处理。
  3. HandlerExceptionResolver:适用于需要高度自定义的异常处理场景。

每种方式都有自己的特点和适用场景,你可以根据实际需求选择合适的方案。记住,优秀的异常处理不仅能让你的程序更健壮,还能提升用户体验。希望这篇文章能帮你轻松掌握 SpringBoot 的全局异常处理!

夜半探案
每日一案,一案一法,一起学习生活中的法律知识。
 最新文章