【Spring Boot】全局异常处理

目录

背景

前言

设计步骤

1.定义异常信息类:

2.自定义异常:

3.创建全局异常处理类

4.在控制器中抛出异常

5.输出

[捕获 @Valid 校验异常](#捕获 @Valid 校验异常)


背景

去面试的时候被问到SpringBoot项目中,如何处理全局异常的,也就是如何捕获全局异常的

前言

在Spring Boot中捕获全局异常是一种有效的方式,可以将应用程序中的所有异常集中处理,提供统一的错误响应,并且可以避免重复编写异常处理逻辑。实现全局异常处理通常使用@ControllerAdvice注解来定义一个全局的异常处理类。在类中编写异常处理方法,并使用@ExceptionHandler注解指定要处理的异常类型。以下是具体的步骤和示例

设计步骤

1.定义异常信息类

通常情况下,我们会定义一个通用的错误信息类,用来包装异常信息返回给客户端。

java 复制代码
public class ErrorDetails {
    private int statusCode;
    private String message;
    private String details;

    public ErrorDetails(int statusCode, String message, String details) {
        super();
        this.statusCode = statusCode;
        this.message = message;
        this.details = details;
    }

    // Getters and Setters
    public int getStatusCode() {
        return statusCode;
    }

    public void setStatusCode(int statusCode) {
        this.statusCode = statusCode;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public String getDetails() {
        return details;
    }

    public void setDetails(String details) {
        this.details = details;
    }
}

2.自定义异常

在实际项目中,我们通常会自定义一些异常,比如资源未找到异常。

java 复制代码
public class ResourceNotFoundException extends RuntimeException {
    public ResourceNotFoundException(String message) {
        super(message);
    }
}

3.创建全局异常处理类

首先,我们需要创建一个带有 @ControllerAdvice 注解的类,这个类可以捕获应用程序中所有控制器(controller)抛出的异常。并使用@ExceptionHandler注解指定要处理的异常类型。

java 复制代码
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.context.request.WebRequest;

@ControllerAdvice
public class GlobalExceptionHandler {

    // 捕获特定异常
    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity<?> resourceNotFoundException(ResourceNotFoundException ex, WebRequest request) {
        ErrorDetails errorDetails = new ErrorDetails(HttpStatus.NOT_FOUND.value(), ex.getMessage(), request.getDescription(false));
        return new ResponseEntity<>(errorDetails, HttpStatus.NOT_FOUND);
    }

    // 捕获全局异常
    @ExceptionHandler(Exception.class)
    public ResponseEntity<?> globalExceptionHandler(Exception ex, WebRequest request) {
        ErrorDetails errorDetails = new ErrorDetails(HttpStatus.INTERNAL_SERVER_ERROR.value(), ex.getMessage(), request.getDescription(false));
        return new ResponseEntity<>(errorDetails, HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

4.在控制器中抛出异常

在控制器中可以抛出自定义的异常,然后由全局异常处理类来捕获并处理。

java 复制代码
@RestController
@RequestMapping("/api")
public class ExportController {

    @Resource
    private UserDao userDao;

    @GetMapping("/resource/{id}")
    public ResponseEntity<User> getResourceById(@PathVariable(value = "id") Integer id) {
        User user = userDao.selectById(id);
        //模拟找不到情况,然后会抛出异常,被全局异常处理器捕捉到
        if(user == null){
            throw new ResourceNotFoundException("Resource not found for this id :: " + id);
        }
        return ResponseEntity.ok(user);
    }
}

5.输出

捕获 @Valid 校验异常

如果你在控制器中使用 @Valid 进行数据校验,可以捕获校验失败时抛出的 MethodArgumentNotValidException。

java 复制代码
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;

@ControllerAdvice
public class GlobalExceptionHandler {

   @ExceptionHandler(MethodArgumentNotValidException.class)
   public ResponseEntity<?> handleValidationException(MethodArgumentNotValidException ex) {
       Map<String, String> errors = new HashMap<>();
       ex.getBindingResult().getAllErrors().forEach((error) -> {
           String fieldName = ((FieldError) error).getField();
           String errorMessage = error.getDefaultMessage();
           errors.put(fieldName, errorMessage);
       });
       return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST);
   }
}

总结

通过 @ControllerAdvice@ExceptionHandler,我们可以在 Spring Boot 中集中管理和处理异常。全局异常处理不仅提高了代码的可维护性,还为用户提供了统一且友好的错误信息。同时,还可以结合日志记录、监控等功能,为应用提供全面的异常管理机制。

相关推荐
考虑考虑15 小时前
docker compose V2版本新属性
运维·后端·自动化运维
mldong15 小时前
一个 App,十三套后端:手机审批端 uni-jeeflow-app 开源了
java·架构
tqs_1234516 小时前
MySQL RR隔离级别死锁|Gap间隙锁、临键锁,订单并发范围查询死锁根因方案
java
逆境不可逃16 小时前
Pi Agent 学习笔记:多个工具怎样并行执行
java
weixin_BYSJ198717 小时前
【计算机毕设】基于SpringBoot与Vue的文物保护档案管理系统08621
vue.js·spring boot·spring cloud·微服务·架构·django·课程设计
GreenTea17 小时前
7000 万 QPS、500 PB:OpenAI 如何用一个 Python 存储平台撑住 10 亿用户
后端·架构
Flynt17 小时前
Java 27 升级实测:默认值动得比新特性多,有个老参数会让 JVM 直接起不来
java·jvm·后端
Bs_MoneyMagnet17 小时前
基于springboot+vue的个人健康管理系统的设计与实现 源码+文档
java·vue.js·spring boot·后端·vue3·springboot3·计算机毕业设计
GreenTea17 小时前
OpenAI Agents API 上手实测:一次调用把整个 agent loop 甩给 OpenAI
前端·后端·算法
星云API技术支持17 小时前
企业微信二次开发:群权限设置、成员管理与群资料维护的接口组合实践
java·前端·企业微信