SpringBoot 如何使用 @ControllerAdvice 注解处理异常消息

简介: SpringBoot 如何使用 @ControllerAdvice 注解处理异常消息

SpringBoot 如何使用 @ControllerAdvice 注解处理异常消息


在 Web 开发中,异常处理是非常重要的一环。在 SpringBoot 框架中,我们通常使用 @ExceptionHandler 注解来处理 Controller 层的异常。但是,如果想要处理全局异常消息,我们需要使用 @ControllerAdvice 注解。本文将介绍如何在 SpringBoot 中使用 @ControllerAdvice 注解处理异常消息。


b64edb27da9ada723dca04215381d27a_523aab074af948a1981b560f99fbc275.png


什么是 @ControllerAdvice


@ControllerAdvice 注解是 Spring Framework 3.2 引入的一个新特性,它用于定义全局异常处理器。使用 @ControllerAdvice 注解,我们可以集中处理所有 Controller 层抛出的异常,而不必在每个 Controller 中单独处理。


@ControllerAdvice 注解通常与 @ExceptionHandler 注解一起使用,@ExceptionHandler 注解用于定义具体的异常处理方法,@ControllerAdvice 注解用于定义全局异常处理器。


如何使用 @ControllerAdvice 进行全局异常处理


使用 @ControllerAdvice 进行全局异常处理的步骤如下:


创建一个全局异常处理类

我们可以创建一个类并使用 @ControllerAdvice 注解进行标注,例如:


@ControllerAdvice
public class GlobalExceptionHandler {
    // 异常处理方法


在上述代码中,我们使用 @ControllerAdvice 注解标注了一个类,并命名为 GlobalExceptionHandler。接下来,我们可以在 GlobalExceptionHandler 类中定义具体的异常处理方法。


定义异常处理方法

在 GlobalExceptionHandler 类中定义具体的异常处理方法,例如:


@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ErrorResponse handleException(Exception e) {
        // 返回 ErrorResponse 对象
    }
}


在上述代码中,我们使用 @ExceptionHandler 注解定义了一个处理 Exception 类型异常的方法,并返回一个 ErrorResponse 对象。在处理方法中,我们可以根据具体的业务需求对异常进行相应的处理,并返回相应的结果。


定义异常返回对象

在异常处理方法中,我们需要返回一个异常返回对象,例如:


@Data
@NoArgsConstructor
@AllArgsConstructor
public class ErrorResponse {
    private int code;
    private String message;
}


在上述代码中,我们定义了一个 ErrorResponse 对象,用于存储异常返回信息。


处理其他类型的异常

除了处理 Exception 类型的异常外,我们还可以根据具体的业务需求,处理其他类型的异常。例如,如果我们想要处理参数校验失败的异常,可以在 GlobalExceptionHandler 类中定义一个处理 MethodArgumentNotValidException 类型异常的方法。


@ControllerAdvice
public class GlobalExceptionHandler {
    // 处理 Exception 类型异常的方法
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public ErrorResponse handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();
        List<ObjectError> allErrors = bindingResult.getAllErrors();
        List<String> errorMessages = new ArrayList<>();
        for (ObjectError error : allErrors) {
            errorMessages.add(error.getDefaultMessage());
        }
        String errorMessage = String.join(",", errorMessages);
        return new ErrorResponse(HttpStatus.BAD_REQUEST.value(), errorMessage);
    }
}

在上述代码中,我们使用 @ExceptionHandler 注解定义了一个处理 MethodArgumentNotValidException 类型异常的方法。在处理方法中,我们首先获取 BindingResult 对象,并遍历其中的所有错误信息,将它们合并为一个错误消息,并返回一个 ErrorResponse 对象。


完整代码示例


下面是一个完整的使用 @ControllerAdvice 进行全局异常处理的示例代码:


@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ErrorResponse handleException(Exception e) {
        return new ErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage());
    }
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public ErrorResponse handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();
        List<ObjectError> allErrors = bindingResult.getAllErrors();
        List<String> errorMessages = new ArrayList<>();
        for (ObjectError error : allErrors) {
            errorMessages.add(error.getDefaultMessage());
        }
        String errorMessage = String.join(",", errorMessages);
        return new ErrorResponse(HttpStatus.BAD_REQUEST.value(), errorMessage);
    }
}
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;
    @PostMapping("/add")
    public Result addUser(@Validated @RequestBody User user) {
        userService.addUser(user);
        return Result.success();
    }
    @GetMapping("/{id}")
    public Result getUserById(@PathVariable("id") Long id) {
        User user = userService.getUserById(id);
        if (user == null) {
            return Result.error("用户不存在");
        }
        return Result.success(user);
    }
}
@Service
public class UserService {
    @Autowired
    private UserDao userDao;
    public void addUser(User user) {
        userDao.save(user);
    }
    public User getUserById(Long id) {
        return userDao.findById(id).orElse(null);
    }
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    @NotNull(message = "用户名不能为空")
    private String username;
    @NotNull(message = "密码不能为空")
    @Size(min = 6, message ="密码长度不能小于6")
    private String password;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result {
    private int code;
    private String message;
    private Object data;
    public static Result success() {
        return new Result(HttpStatus.OK.value(), "操作成功", null);
    }
    public static Result success(Object data) {
        return new Result(HttpStatus.OK.value(), "操作成功", data);
    }
    public static Result error(String message) {
        return new Result(HttpStatus.BAD_REQUEST.value(), message, null);
    }
}

在上述代码中,我们定义了一个 GlobalExceptionHandler 类,使用 @ControllerAdvice 注解标注,并在其中定义了处理 Exception 和 MethodArgumentNotValidException 类型异常的方法。


我们还定义了一个 UserController 类和一个 UserService 类,用于处理用户相关的业务逻辑。在 UserController 类中,我们使用 @Validated 注解对 User 对象进行参数校验,并在 User 类中使用了 javax.validation.constraints 包中的注解对 username 和 password 属性进行了校验。如果参数校验失败,会触发 MethodArgumentNotValidException 异常,在 GlobalExceptionHandler 类中的 handleMethodArgumentNotValidException 方法中进行处理。


在 UserController 类中,我们使用 Result 类作为接口返回值对象,用于封装接口返回结果。在 Result 类中,我们定义了一个静态方法 success 和 error,用于生成成功和失败的返回结果,并定义了 code、message 和 data 三个属性,用于封装返回结果的状态码、消息和数据。


总结


在本文中,我们介绍了如何在 SpringBoot 中使用 @ControllerAdvice 注解处理异常消息。通过使用 @ControllerAdvice 注解,我们可以集中处理所有 Controller 层抛出的异常,而不必在每个 Controller 中单独处理。在 GlobalExceptionHandler 类中定义异常处理方法,并根据具体的业务需求对异常进行相应的处理,可以大大提高代码的可维护性和可读性。


相关文章
|
20天前
|
Java Spring
在使用Spring的`@Value`注解注入属性值时,有一些特殊字符需要注意
【10月更文挑战第9天】在使用Spring的`@Value`注解注入属性值时,需注意一些特殊字符的正确处理方法,包括空格、引号、反斜杠、新行、制表符、逗号、大括号、$、百分号及其他特殊字符。通过适当包裹或转义,确保这些字符能被正确解析和注入。
|
9天前
|
XML JSON Java
SpringBoot必须掌握的常用注解!
SpringBoot必须掌握的常用注解!
30 4
SpringBoot必须掌握的常用注解!
|
5天前
|
Dubbo Java 应用服务中间件
深入探讨了“dubbo+nacos+springboot3的native打包成功后运行出现异常”的原因及解决方案
本文深入探讨了“dubbo+nacos+springboot3的native打包成功后运行出现异常”的原因及解决方案。通过检查GraalVM版本兼容性、配置反射列表、使用代理类、检查配置文件、禁用不支持的功能、查看日志文件、使用GraalVM诊断工具和调整GraalVM配置等步骤,帮助开发者快速定位并解决问题,确保服务的正常运行。
19 1
|
11天前
|
存储 缓存 Java
Spring缓存注解【@Cacheable、@CachePut、@CacheEvict、@Caching、@CacheConfig】使用及注意事项
Spring缓存注解【@Cacheable、@CachePut、@CacheEvict、@Caching、@CacheConfig】使用及注意事项
47 2
|
11天前
|
JSON Java 数据库
SpringBoot项目使用AOP及自定义注解保存操作日志
SpringBoot项目使用AOP及自定义注解保存操作日志
27 1
|
2天前
|
XML Java 数据格式
SpringBoot入门(8) - 开发中还有哪些常用注解
SpringBoot入门(8) - 开发中还有哪些常用注解
9 0
|
25天前
|
架构师 Java 开发者
得物面试:Springboot自动装配机制是什么?如何控制一个bean 是否加载,使用什么注解?
在40岁老架构师尼恩的读者交流群中,近期多位读者成功获得了知名互联网企业的面试机会,如得物、阿里、滴滴等。然而,面对“Spring Boot自动装配机制”等核心面试题,部分读者因准备不足而未能顺利通过。为此,尼恩团队将系统化梳理和总结这一主题,帮助大家全面提升技术水平,让面试官“爱到不能自已”。
得物面试:Springboot自动装配机制是什么?如何控制一个bean 是否加载,使用什么注解?
|
5天前
|
存储 安全 Java
springboot当中ConfigurationProperties注解作用跟数据库存入有啥区别
`@ConfigurationProperties`注解和数据库存储配置信息各有优劣,适用于不同的应用场景。`@ConfigurationProperties`提供了类型安全和模块化的配置管理方式,适合静态和简单配置。而数据库存储配置信息提供了动态更新和集中管理的能力,适合需要频繁变化和集中管理的配置需求。在实际项目中,可以根据具体需求选择合适的配置管理方式,或者结合使用这两种方式,实现灵活高效的配置管理。
8 0
|
30天前
|
XML Java 数据库
Spring boot的最全注解
Spring boot的最全注解
|
1月前
|
JSON NoSQL Java
springBoot:jwt&redis&文件操作&常见请求错误代码&参数注解 (九)
该文档涵盖JWT(JSON Web Token)的组成、依赖、工具类创建及拦截器配置,并介绍了Redis的依赖配置与文件操作相关功能,包括文件上传、下载、删除及批量删除的方法。同时,文档还列举了常见的HTTP请求错误代码及其含义,并详细解释了@RequestParam与@PathVariable等参数注解的区别与用法。
下一篇
无影云桌面