Spring Boot全局异常
Spring Boot全局异常处理是一种机制,用于处理应用程序中出现的所有未处理异常。当应用程序遇到未处理的异常时,全局异常处理机制将捕获该异常并返回一个可读的错误响应给客户端,以避免应用程序崩溃或返回不友好的错误信息给用户。全局异常处理可以帮助开发人员更好地跟踪和调试应用程序的异常情况,并提供更好的用户体验。在Spring Boot中,可以使用@ExceptionHandler注解和@ControllerAdvice注解来实现全局异常处理。
应用
在 Spring Boot 应用程序中,实现全局异常处理是确保应用程序稳定性和用户友好的重要步骤。全局异常处理可以帮助捕捉和处理所有未被处理的异常,并返回一致且有用的错误响应。Spring Boot 提供了多种方式来实现全局异常处理,主要通过使用 `@ControllerAdvice` 和 `@ExceptionHandler` 注解。
以下是实现全局异常处理的步骤和示例:
1. **使用 `@ControllerAdvice` 和 `@ExceptionHandler`**
#### a. **创建全局异常处理类**
`@ControllerAdvice` 注解用于定义一个全局的异常处理器,该类可以捕捉所有控制器抛出的异常。`@ExceptionHandler` 注解用于指定具体的异常类型及其处理方法。
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.ResponseBody;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
@ResponseBody
public ErrorResponse handleResourceNotFoundException(ResourceNotFoundException ex) {
return new ErrorResponse(HttpStatus.NOT_FOUND.value(), ex.getMessage());
}
@ExceptionHandler(IllegalArgumentException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public ErrorResponse handleIllegalArgumentException(IllegalArgumentException ex) {
return new ErrorResponse(HttpStatus.BAD_REQUEST.value(), ex.getMessage());
}
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
public ErrorResponse handleGlobalException(Exception ex) {
return new ErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR.value(), "An unexpected error occurred");
}
}
#### b. **创建错误响应类**
定义一个通用的错误响应类,用于返回给客户端的错误信息。
public class ErrorResponse {
private int status;
private String message;
public ErrorResponse(int status, String message) {
this.status = status;
this.message = message;
}
// Getters and setters
}
2. **自定义异常**
你可以创建自定义异常类以表示特定类型的错误:
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(String message) {
super(message);
}
}
3. **使用 `@ResponseStatus` 注解**
除了在 `@ExceptionHandler` 中设置状态码外,你还可以直接在自定义异常类上使用 `@ResponseStatus` 注解来设置响应状态码:
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(String message) {
super(message);
}
}
4. **使用 `ResponseEntityExceptionHandler`**
对于更复杂的异常处理需求,可以扩展 `ResponseEntityExceptionHandler`,这是 Spring 提供的用于处理标准 Spring MVC 异常的基类。
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
@ControllerAdvice
public class CustomExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<Object> handleResourceNotFoundException(ResourceNotFoundException ex, WebRequest request) {
ErrorResponse errorResponse = new ErrorResponse(HttpStatus.NOT_FOUND.value(), ex.getMessage());
return new ResponseEntity<>(errorResponse, HttpStatus.NOT_FOUND);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<Object> handleGlobalException(Exception ex, WebRequest request) {
ErrorResponse errorResponse = new ErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR.value(), "An unexpected error occurred");
return new ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
5. **异常处理的最佳实践**
- **记录异常**:确保在处理异常时记录异常信息,以便后续分析和调试。可以使用日志框架(如 Logback 或 Log4j2)记录详细的错误日志。
- **返回一致的错误响应**:确保错误响应具有一致的结构,以便客户端可以一致地处理错误。
- **考虑客户端体验**:提供清晰且用户友好的错误消息,不暴露内部实现细节。
6. **示例项目结构**
项目结构可以如下:
src/main/java
└── com
└── example
├── controller
│ └── MyController.java
├── exception
│ ├── GlobalExceptionHandler.java
│ ├── ResourceNotFoundException.java
│ └── ErrorResponse.java
└── Application.java
- **`MyController.java`**:包含业务逻辑的控制器。
- **`GlobalExceptionHandler.java`**:处理全局异常。
- **`ResourceNotFoundException.java`**:自定义异常类。
- **`ErrorResponse.java`**:错误响应类。
- **`Application.java`**:应用程序主类。
总结
在 Spring Boot 中实现全局异常处理可以帮助你统一管理异常响应,提供一致的错误信息,并提高应用程序的可维护性。通过使用 `@ControllerAdvice` 和 `@ExceptionHandler` 注解、创建自定义异常和错误响应类,你可以高效地处理应用程序中的异常情况。