全局异常处理器
当存在很多自定义异常类时,编写全局异常处理器需要系统性地对不同类型的异常进行分类处理,以保证代码的清晰性和可维护性。下面为你详细介绍实现方法和示例代码。
实现思路
- 定义自定义异常类:为不同的业务场景创建对应的自定义异常类,这些类通常继承自
RuntimeException
或其他合适的异常类。 - 创建全局异常处理器类:使用
@ControllerAdvice
注解标记一个类作为全局异常处理器,在该类中使用@ExceptionHandler
注解来定义处理不同异常类型的方法。 - 分类处理异常:根据异常的类型和业务需求,为不同的自定义异常类编写专门的处理方法,同时提供一个通用的异常处理方法来处理未被明确捕获的异常。
示例代码
1. 定义多个自定义异常类
// 业务异常基类
public class BusinessException extends RuntimeException {
public BusinessException(String message) {
super(message);
}
}
// 用户相关业务异常
public class UserException extends BusinessException {
public UserException(String message) {
super(message);
}
}
// 订单相关业务异常
public class OrderException extends BusinessException {
public OrderException(String message) {
super(message);
}
}
2. 创建全局异常处理器类
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice
public class GlobalExceptionHandler {
// 处理用户相关业务异常
@ExceptionHandler(UserException.class)
public ResponseEntity<String> handleUserException(UserException e) {
return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
}
// 处理订单相关业务异常
@ExceptionHandler(OrderException.class)
public ResponseEntity<String> handleOrderException(OrderException e) {
return new ResponseEntity<>(e.getMessage(), HttpStatus.CONFLICT);
}
// 处理其他业务异常
@ExceptionHandler(BusinessException.class)
public ResponseEntity<String> handleBusinessException(BusinessException e) {
return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
}
// 处理其他未被捕获的异常
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleGeneralException(Exception e) {
return new ResponseEntity<>("An unexpected error occurred: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
3. 业务代码中抛出异常
import org.springframework.stereotype.Service;
@Service
public class UserService {
public void validateUser(String username) {
if (username == null || username.isEmpty()) {
throw new UserException("Username cannot be empty");
}
// 其他业务逻辑
}
}
@Service
public class OrderService {
public void createOrder() {
// 模拟订单创建失败
throw new OrderException("Order creation failed due to insufficient stock");
}
}
4. 控制器调用业务方法
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@Autowired
private UserService userService;
@Autowired
private OrderService orderService;
@GetMapping("/validateUser")
public String validateUser(@RequestParam String username) {
userService.validateUser(username);
return "User validation passed";
}
@GetMapping("/createOrder")
public String createOrder() {
orderService.createOrder();
return "Order created successfully";
}
}
代码解释
- 自定义异常类:
BusinessException
作为业务异常的基类,UserException
和OrderException
继承自BusinessException
,用于区分不同业务场景下的异常。 - 全局异常处理器:
GlobalExceptionHandler
类使用@ControllerAdvice
注解,其中每个@ExceptionHandler
注解的方法负责处理特定类型的异常。对于不同的自定义异常类,返回不同的 HTTP 状态码和错误信息。 - 业务代码:在
UserService
和OrderService
中,根据业务逻辑抛出相应的自定义异常。 - 控制器:
UserController
调用业务方法,当业务方法抛出异常时,全局异常处理器会自动捕获并处理。
通过上述方法,你可以清晰地对多个自定义异常类进行分类处理,提高代码的可维护性和可读性。
Spring 文章被收录于专栏
Spring 生态是以 Spring Framework 为核心,衍生出的一系列相互关联、功能互补的技术和工具集合,用于简化企业级应用开发,覆盖从单体应用到分布式微服务、从 Web 开发到数据处理等诸多场景。