文章插图
在Spring框架中,@ControllerAdvice是全局异常处理机制,用于集中处理应用程序中发生的异常 。
当任何控制器方法(例如REST端点)抛出异常时,该异常会被@ControllerAdvice注解的类捕获 。
@ControllerAdvice类中的@ExceptionHandler方法用于处理特定类型的异常 , 并返回适当的响应 。
文章插图
本文我们通过一个实际场景的例子来详细说明,在Spring Boot应用程序中处理产品相关的自定义异常并进行全局处理的情况 。
步骤:
1. 创建自定义的ProductNotFoundException:在这一步中,我们创建一个自定义异常类ProductNotFoundException,它继承自RuntimeException 。这个自定义异常用于表示系统中找不到产品的情况 。通过创建自定义异常,我们可以提供更具体的错误信息 。
public class ProductNotFoundException extends RuntimeException { public ProductNotFoundException(Long productId) { super(“Product not found with ID: “ + productId); }}
解释:- 自定义异常用于捕获应用程序特定的错误场景 。
- 在这种情况下,我们在异常消息中包含了productId,以提供有关缺失产品的详细信息 。
@Servicepublic class ProductService {public Product getProductById(Long productId) {// 模拟获取产品的逻辑Product product = getProductFromDatabase(productId);if (product == null) {throw new ProductNotFoundException(productId);}return product;}// 模拟从数据库获取产品的方法private Product getProductFromDatabase(Long productId) {// 在这里实现您的数据库逻辑// 如果找不到产品,则返回nullreturn null;}}
解释:- ProductService封装了与产品相关的业务逻辑 。
- getProductById方法模拟从数据库或其他数据源获取产品 。
- 如果找不到产品(基于模拟),会抛出ProductNotFoundException 。
@ControllerAdvicepublic class GlobalExceptionHandler {@ExceptionHandler(ProductNotFoundException.class)public ResponseEntity<ErrorResponse> handleProductNotFoundException(ProductNotFoundException ex) {ErrorResponse errorResponse = new ErrorResponse(HttpStatus.NOT_FOUND.value(), ex.getMessage());return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorResponse);}}
解释:- @ControllerAdvice将该类标记为全局异常处理器,使其能够处理来自多个控制器的异常 。
- 处理器内的@ExceptionHandler方法捕获ProductNotFoundException 。
- 它使用异常中的自定义错误消息构建一个包含404 Not Found状态码的ErrorResponse对象 。
- 处理器返回包含错误详细信息的JSON响应 。
public class ErrorResponse {private int statusCode;private String message;public ErrorResponse(int statusCode, String message) {this.statusCode = statusCode;this.message = message;}// Getter方法}
解释:- ErrorResponse类提供了一个标准化的错误响应格式 。
- 它包含HTTP状态码和描述错误的消息字段 。
@RestController@RequestMApping("/api/products")public class ProductController {@Autowiredprivate ProductService productService;@GetMapping("/{productId}")public ResponseEntity<Product> getProduct(@PathVariable Long productId) {Product product = productService.getProductById(productId);return ResponseEntity.ok(product);}}
解释:- Spring Boot是如何处理HTTP请求的?
- Spring Cloud 微服务系列之 ShardingSphere-Proxy 数据库代理
- Spring Cloud Gateway提供的简易网关实现方式,你使用过吗?
- SpringBoot拦截器和动态代理有什么区别?
- 详解Spring支持的各种数据类型的注入,你都用过哪些?
- RestTemplate详解 Springboot — 用更优雅的方式发HTTP请求
- ELK 处理 Spring Boot 日志,不错!
- Spring中这两个对象ObjectFactory与FactoryBean接口你使用过吗?
- pringBoot如何实现热部署?
- Spring定义Controller接口的这些方式你肯定不知道