全局异常处理
全局异常处理
完整的 Spring Boot 全局异常处理示例,使用 @RestControllerAdvice
,支持系统异常、自定义业务异常,并返回统一 JSON 响应,同时打印日志。
1️⃣ 自定义异常类
| package com.example.demo.exception;
public class BusinessException extends RuntimeException {
private final int code;
public BusinessException(int code, String message) {
super(message);
this.code = code;
}
public int getCode() {
return code;
}
}
|
2️⃣ 统一响应类
| package com.example.demo.dto;
import java.time.LocalDateTime;
public class ErrorResponse {
private int code; // 错误码
private String message; // 错误信息
private LocalDateTime time; // 时间戳
private String path; // 请求路径
public ErrorResponse(int code, String message, LocalDateTime time, String path) {
this.code = code;
this.message = message;
this.time = time;
this.path = path;
}
// getter & setter
public int getCode() { return code; }
public String getMessage() { return message; }
public LocalDateTime getTime() { return time; }
public String getPath() { return path; }
}
|
3️⃣ 全局异常处理器
| package com.example.demo.exception;
import com.example.demo.dto.ErrorResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
@RestControllerAdvice
public class GlobalExceptionHandler {
private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
// 处理自定义业务异常
@ExceptionHandler(BusinessException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ErrorResponse handleBusinessException(BusinessException ex, HttpServletRequest request) {
log.warn("BusinessException: {}", ex.getMessage());
return new ErrorResponse(
ex.getCode(),
ex.getMessage(),
LocalDateTime.now(),
request.getRequestURI()
);
}
// 处理所有未捕获异常
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ErrorResponse handleException(Exception ex, HttpServletRequest request) {
log.error("Exception: ", ex);
return new ErrorResponse(
500,
"系统错误,请联系管理员",
LocalDateTime.now(),
request.getRequestURI()
);
}
}
|
4️⃣ 使用示例
| @GetMapping("/deleteDept/{id}")
public String deleteDept(@PathVariable Integer id) {
if (emps != null && !emps.isEmpty()) {
throw new BusinessException(1001, "此部门下有员工,不能删除!");
}
return "删除成功";
}
|
5️⃣ 返回示例
自定义异常
| {
"code": 1001,
"message": "此部门下有员工,不能删除!",
"time": "2025-08-25T21:50:12.345",
"path": "/deleteDept/1"
}
|
系统异常
| {
"code": 500,
"message": "系统错误,请联系管理员",
"time": "2025-08-25T21:51:10.678",
"path": "/someApi"
}
|
✅ 特点总结:
- 全局生效,不需要在 Controller 单独 try-catch。
- 区分业务异常与系统异常。
- 返回统一 JSON 响应结构,便于前端处理。
- 支持日志记录,方便排查问题。