前言
在开发大型 Web 应用时,统一的异常处理是保持代码整洁和维护性的关键所在。Spring Boot 提供了方便的方法来帮助我们实现全局的异常管理。带着大家学习如何在 Spring Boot 中实现全局的异常处理。
为什么需要全局异常管理?
以下是一段没有全局异常管理的示例代码:
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ProductController {
@GetMapping("/product/{id}")
public ResponseEntity<String> getProduct(@PathVariable String id) {
try {
int productId = Integer.parseInt(id);
// 判断产品 ID 是否合规
if (productId <= 0) {
throw new IllegalArgumentException("Product ID must be greater than 0");
}
// 假设这里是一个查找产品的逻辑
String productInfo = "Product Info for ID: " + id;
return ResponseEntity.ok(productInfo);
} catch (NumberFormatException e) {
// 捕获 ID 不是数字的情况
return ResponseEntity.badRequest().body("Invalid Product ID format");
} catch (IllegalArgumentException e) {
// 捕获产品 ID 小于等于0的情况
return ResponseEntity.badRequest().body(e.getMessage());
} catch (Exception e) {
// 捕获所有其他类型的异常
return ResponseEntity.status(500).body("An unexpected error occurred");
}
}
}
在没有全局异常管理的情况下,每个控制器或 service
服务中可能都会有各种 try-catch
代码块来捕获和处理异常。这样会导致以下问题:
- 代码重复:相同的异常处理逻辑会在多处重复出现。
- 不一致的响应格式:不同的开发人员可能采用不同的方式来处理同一种异常,从而导致响应格式不统一。
- 增加维护成本:未来对异常处理逻辑的任何更改都需要在多个地方进行修改。
- 可读性差:
try-catch
块使得主要的业务逻辑被异常处理代码包围,这可能会让代码的主要逻辑不够明显,降低代码的可读性。
通过实现全局异常管理,我们可以避免上述问题,确保应用在出现异常时始终有一致和统一的行为。
自定义业务异常
在企业级应用中,除了系统异常,很多时候我们还需要处理业务异常。与系统异常不同,业务异常通常表示一个预期的、合理的错误,例如用户输入的数据无效、所请求的资源不存在等。我们需要区分这些异常,并为它们给调用者提供友好的错误提示。通常来说,比较推荐的做法是,将自定义业务异常整合到全局异常管理中,使其更加统一且易于维护。
自定义一个基础异常接口
首先,在xx-module-common
公共模块中新建 exception
包,用于统一放置和异常相关的代码。然后,创建一个