以下是一个更详细的基于 Java 的 Spring Boot 框架的全局异常处理类示例。这个示例将涵盖常见的异常处理场景,包括自定义异常、系统异常以及特定的业务异常。
### 一、定义异常响应实体
首先,我们需要定义一个统一的响应实体类,用于封装返回给客户端的错误信息。这个类通常包含状态码、错误信息和可选的数据字段。
```java
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ApiResponse<T> {
private int code;
private String message;
private T data;
public ApiResponse(int code, String message, T data) {
this.code = code;
this.message = message;
this.data = data;
}
public static <T> ApiResponse<T> success(T data) {
return new ApiResponse<>(200, "Success", data);
}
public static <T> ApiResponse<T> error(int code, String message) {
return new ApiResponse<>(code, message, null);
}
}
```
### 二、定义自定义异常类
为了更好地处理业务逻辑中的错误,我们通常会定义一些自定义异常类。这些异常类可以携带额外的错误信息,便于全局异常处理器进行处理。
```java
public class ResourceNotFoundException extends RuntimeException {
private int statusCode;
public ResourceNotFoundException(String message, int statusCode) {
super(message);
this.statusCode = statusCode;
}
public int getStatusCode() {
return statusCode;
}
}
```
### 三、创建全局异常处理器
全局异常处理器是整个异常处理机制的核心。它使用 `@ControllerAdvice` 或 `@RestControllerAdvice` 注解,可以捕获并处理所有控制器中抛出的异常。
```java
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
@ControllerAdvice
public class GlobalExceptionHandler {
// 处理自定义异常
@ExceptionHandler(ResourceNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
@ResponseBody
public ApiResponse<String> handleResourceNotFoundException(ResourceNotFoundException ex) {
return ApiResponse.error(ex.getStatusCode(), ex.getMessage());
}
// 处理系统异常
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
public ApiResponse<String> handleException(Exception ex) {
return ApiResponse.error(500, "Internal Server Error: " + ex.getMessage());
}
// 处理特定的业务异常(例如,参数校验失败)
@ExceptionHandler(IllegalArgumentException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public ApiResponse<String> handleIllegalArgumentException(IllegalArgumentException ex) {
return ApiResponse.error(400, "Invalid Request: " + ex.getMessage());
}
}
```
### 四、使用示例
#### 1. 控制器代码
在控制器中,你可以直接抛出异常,而不需要手动处理异常逻辑。全局异常处理器会自动捕获并处理这些异常。
```java
@RestController
@RequestMapping("/api")
public class SampleController {
@GetMapping("/test")
public String test() {
throw new ResourceNotFoundException("Resource not found", 404);
}
@GetMapping("/validate")
public String validate() {
throw new IllegalArgumentException("Invalid input");
}
}
```
#### 2. 测试结果
- 访问 `/api/test` 时,会触发 `ResourceNotFoundException`,返回以下响应:
```json
{
"code": 404,
"message": "Resource not found"
}
```
- 访问 `/api/validate` 时,会触发 `IllegalArgumentException`,返回以下响应:
```json
{
"code": 400,
"message": "Invalid Request: Invalid input"
}
```
- 如果抛出其他未捕获的异常,会触发 `handleException` 方法,返回以下响应:
```json
{
"code": 500,
"message": "Internal Server Error: [Exception message]"
}
```
### 五、扩展功能
#### 1. 日志记录
在全局异常处理器中,可以添加日志记录功能,方便排查问题。例如:
```java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ControllerAdvice
public class GlobalExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
public ApiResponse<String> handleException(Exception ex) {
logger.error("Unhandled exception occurred", ex);
return ApiResponse.error(500, "Internal Server Error: " + ex.getMessage());
}
}
```
#### 2. 统一返回格式
如果需要对所有响应进行统一格式化,可以在全局异常处理器中处理所有响应,而不仅仅是异常响应。例如:
```java
@ExceptionHandler(value = Exception.class)
public ResponseEntity<ApiResponse<String>> handleException(Exception ex) {
ApiResponse<String> response = ApiResponse.error(500, "Internal Server Error: " + ex.getMessage());
return new ResponseEntity<>(response, HttpStatus.INTERNAL_SERVER_ERROR);
}
```
### 六、总结
通过全局异常处理器,你可以实现以下目标:
1. **统一异常处理**:避免在每个方法中重复编写异常处理逻辑。
2. **统一响应格式**:无论是正常响应还是异常响应,都返回一致的格式。
3. **更好的日志记录**:在全局异常处理器中记录异常日志,便于排查问题。
这个示例展示了如何在 Spring Boot 中实现全局异常处理,你可以根据实际需求进行扩展和调整。

1712

被折叠的 条评论
为什么被折叠?



