一、为什么需要全局异常处理器?
-
统一异常处理:在应用程序中,可能会出现各种各样的异常情况,如数据库连接失败、资源不存在、权限问题等等。全局异常处理器允许我们统一处理这些异常,而不是在每个地方都去处理它们,会省去大部分
try-catch
代码。 -
提高可维护性:通过集中处理异常,可以使代码更加清晰易懂,减少重复的异常处理代码。
-
友好的用户体验:通过全局异常处理器,我们可以提供友好的错误信息给用户,而不是让他们看到一堆堆栈跟踪信息。
二、如何使用全局异常处理器?
在 Spring Boot 中,使用全局异常处理器非常简单。主要步骤如下:
-
使用
@ControllerAdvice
注解标记一个类。 -
在类中定义异常处理方法,并使用
@ExceptionHandler
注解标记这些方法,指定要处理的异常类型。 -
在异常处理方法中编写处理异常的逻辑,可以返回自定义的错误信息。
三、示例应用案例
假设我们正在开发一个电子商务网站,其中有一个商品详情页,用户可以通过访问 /product/{productId}
来查看商品详情。如果用户访问的商品不存在,我们希望能够给用户友好的错误提示。
首先,我们创建一个全局异常处理器类 GlobalExceptionHandler
:
@ControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(ProductNotFoundException.class)public ResponseEntity<String> handleProductNotFoundException(ProductNotFoundException ex) {return ResponseEntity.status(HttpStatus.NOT_FOUND).body("商品不存在,请检查您输入的商品ID");}
}
在上面的代码中,我们使用 @ControllerAdvice
注解标记了 GlobalExceptionHandler
类,表明它是一个全局异常处理器。然后,我们定义了一个方法 handleProductNotFoundException
,并使用 @ExceptionHandler
注解标记这个方法,指定它处理 ProductNotFoundException
这种异常。在方法中,我们返回了一个包含友好错误信息的 ResponseEntity
对象。
然后,我们定义一个 ProductNotFoundException
异常类:
public class ProductNotFoundException extends RuntimeException {// 可以根据需要添加一些自定义的异常信息或其他属性
}
最后,在我们的 Controller 类中,当用户请求一个不存在的商品时抛出 ProductNotFoundException
异常:
@RestController
public class ProductController {@Autowiredprivate ProductService productService;@GetMapping("/product/{productId}")public Product getProductById(@PathVariable Long productId) {Product product = productService.getProductById(productId);if (product == null) {throw new ProductNotFoundException();}return product;}
}
现在,当用户访问一个不存在的商品时,全局异常处理器会捕获到 ProductNotFoundException
异常,并返回一个包含友好错误信息的响应,让用户知道该商品不存在。