跳转至

全局异常处理

全局异常处理

完整的 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️⃣ 使用示例

1
2
3
4
5
6
7
@GetMapping("/deleteDept/{id}")
public String deleteDept(@PathVariable Integer id) {
    if (emps != null && !emps.isEmpty()) {
        throw new BusinessException(1001, "此部门下有员工,不能删除!");
    }
    return "删除成功";
}

5️⃣ 返回示例

自定义异常

1
2
3
4
5
6
{
  "code": 1001,
  "message": "此部门下有员工,不能删除!",
  "time": "2025-08-25T21:50:12.345",
  "path": "/deleteDept/1"
}

系统异常

1
2
3
4
5
6
{
  "code": 500,
  "message": "系统错误,请联系管理员",
  "time": "2025-08-25T21:51:10.678",
  "path": "/someApi"
}

✅ 特点总结:

  1. 全局生效,不需要在 Controller 单独 try-catch。
  2. 区分业务异常与系统异常。
  3. 返回统一 JSON 响应结构,便于前端处理。
  4. 支持日志记录,方便排查问题。