@RestControllerAdvice 统一异常处理

简介: @RestControllerAdvice 统一异常处理

是什么

@RestControllerAdvice 统一异常处理

@RestControllerAdvice是一个组合注解,由@ControllerAdvice、@ResponseBody组成


ControllerAdvice和RestControllerAdvice的区别

两者都是全局捕获异常,但是RestControllerAdvice更加强大,其作用相当于ControllerAdvice+ResponseBody


basePackages: 指定一个或多个包,这些包及其子包下的所有 Controller 都被该 @ControllerAdvice 管理


@ExceptionHandler(value = Exception.class) ExceptionHandler的作用是用来捕获指定的异常。


为什么要有这个注解


对于异常处理情况,我们也需要统一成上面的格式。如果我们在controller中通过try catch来处理异常的话,会出现一个问题就是每个函数里都加一个Try catch,代码会变的很乱。下面我们就通过spring boot的注解来省略掉controller中的try-catch 帮助我们来封装异常信息并返回给前端,这样用户也不会得到一些奇奇怪怪的错误提示。


怎么用

假设有枚举

public enum BizCodeEnume {
    UNKNOW_EXCEPTION(10000,"系统未知异常"),
    VAILD_EXCEPTION(10001,"参数格式校验失败");
    private int code;
    private String msg;
    BizCodeEnume(int code,String msg){
        this.code = code;
        this.msg = msg;
    }
    public int getCode() {
        return code;
    }
    public String getMsg() {
        return msg;
    }
}

控制层

    /**
     * 保存
     */
    @RequestMapping("/save")
    public R save(@Valid @RequestBody BrandEntity brand, BindingResult result){
        if(result.hasErrors()){
            //1.获取校验错误的结果
            Map<String, String> map = new HashMap<>();
            result.getFieldErrors().forEach((item)->{
           //FieldError获取到错误的提示
           String message = item.getDefaultMessage();
            //获取错误的属性的名字
           String field = item.getField();
           map.put(field,message);
           System.out.println("******");
       });
            return R.error(400,"提交的数据不合法").put("data",map);
        }
            brandService.save(brand);
            return R.ok();
    }

这个控制层主要是接受请求对象保存到数据库中,为防止老6跳过前端的页面,用postman发送请求。需要对请求对象进行判断 ,这里直接在BrandEntity 这个类上用


/**

* jsr303

* 1)给bean添加校验注解,并定义自己的message提示

* 2)开启校验功能@valid

* 效果:校验错误以后会有默认的响应

* 3)给校验的bean后紧跟一个bindingResult ,就可以获取到校验结果

*/


@Data
@TableName("pms_brand")
public class BrandEntity implements Serializable {
  private static final long serialVersionUID = 1L;
  /**
   * 品牌id
   */
  @TableId
  private Long brandId;
  /**
   * 品牌名
   */
  @NotBlank(message = "品牌名必须提交")
  private String name;
  /**
   * 品牌logo地址
   */
  @NotEmpty
  @URL(message = "logo必须是一个url地址")
  private String logo;
  /**
   * 介绍
   */
  private String descript;
  /**
   * 显示状态[0-不显示;1-显示]
   */
  @NotNull
  private Integer showStatus;
  /**
   * 检索首字母
   */
    @NotEmpty
    @Pattern(regexp = "/^[a-zA-Z]$/",message = "检索首字母必须是首字母")
  private String firstLetter;
  /**
   * 排序
   */
  @Min(value = 0,message = "排序必须大于等于0")
  private Integer sort;
}

大家可以看到在控制层的判断还是十分繁琐 ,这个时候使用@RestControllerAdvice 解决

@Slf4j
@RestControllerAdvice(basePackages = "com.atguigu.gulimall.product.controller")
public class GulimallExceptionControllerAdvice {
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public R handleVaildException(MethodArgumentNotValidException e){
        Map<String, String> map = new HashMap<>();
        log.error("数据校验出现问题{},异常类型:{}",e.getMessage(),e.getClass());
        BindingResult bindingResult = e.getBindingResult();
        bindingResult.getFieldErrors().forEach((item)->{
          map.put(item.getField(),item.getDefaultMessage());
        });
        return R.error(BizCodeEnume.VAILD_EXCEPTION.getCode(),BizCodeEnume.VAILD_EXCEPTION.getMsg()).put("data",map);
    }
    @ExceptionHandler(value = Throwable.class)
    public  R all(Exception e){
        log.error("出现问题{},异常类型:{}",e.getMessage(),e.getClass());
        return R.error(BizCodeEnume.UNKNOW_EXCEPTION.getCode(),BizCodeEnume.UNKNOW_EXCEPTION.getMsg());
    }
}

控制层可以简化为

    @RequestMapping("/save")
    public R save(@Valid @RequestBody BrandEntity brand/*, BindingResult result*/){
//        if(result.hasErrors()){
//            //1.获取校验错误的结果
//            Map<String, String> map = new HashMap<>();
//            result.getFieldErrors().forEach((item)->{
//           //FieldError获取到错误的提示
//           String message = item.getDefaultMessage();
//            //获取错误的属性的名字
//           String field = item.getField();
//           map.put(field,message);
//           System.out.println("******");
//       });
//            return R.error(400,"提交的数据不合法").put("data",map);
//        }
            brandService.save(brand);
            return R.ok();
    }

7648368984694bacbf1f34819a81c4a1.png


相关文章
|
Java 测试技术 Spring
springboot测试环境无法注入bean问题分析及解决方案
springboot测试环境无法注入bean问题分析及解决方案
5075 0
springboot测试环境无法注入bean问题分析及解决方案
|
安全 Java 数据库
Spring Security 实战指南:从入门到精通
本文详细介绍了Spring Security在Java Web项目中的应用,涵盖登录、权限控制与安全防护等功能。通过Filter Chain过滤器链实现请求拦截与认证授权,核心组件包括AuthenticationProvider和UserDetailsService,负责用户信息加载与密码验证。文章还解析了项目结构,如SecurityConfig配置类、User实体类及自定义登录逻辑,并探讨了Method-Level Security、CSRF防护、Remember-Me等进阶功能。最后总结了Spring Security的核心机制与常见配置,帮助开发者构建健壮的安全系统。
2373 0
|
Kubernetes Cloud Native 调度
《分布式任务调度框架深度对比:Quartz/XXL-JOB/Elastic-Job/PowerJob选型指南》​
根据IDC预测,到2025年全球将有75%的企业任务调度系统需要重构以适应云原生架构。技术雷达监测:定期关注CNCF技术趋势报告渐进式改造:从非核心业务开始验证新框架人才储备:重点培养具备K8s Operator开发能力的调度专家评估现有系统的云原生适配度在测试环境部署PowerJob 4.3.3参与CNCF调度技术社区讨论制定6个月框架迁移路线图(注:本文数据来自各框架官方路线图、CNCF年度报告及笔者压力测试结果,转载请保留出处)
2861 0
|
Java Maven
Maven编译报错:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.13.0:compile 解决方案
在执行Maven项目中的`install`命令时,遇到编译插件版本不匹配的错误。具体报错为:`maven-compiler-plugin:3.13.0`要求Maven版本至少为3.6.3。解决方案是将Maven版本升级到3.6.3或降低插件版本。本文详细介绍了如何下载、解压并配置Maven 3.6.3,包括环境变量设置和IDEA中的Maven配置,确保项目顺利编译。
17623 5
Maven编译报错:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.13.0:compile 解决方案
|
NoSQL Java Redis
Spring Boot 自动配置机制:从原理到自定义
Spring Boot 的自动配置机制通过 `spring.factories` 文件和 `@EnableAutoConfiguration` 注解,根据类路径中的依赖和条件注解自动配置所需的 Bean,大大简化了开发过程。本文深入探讨了自动配置的原理、条件化配置、自定义自动配置以及实际应用案例,帮助开发者更好地理解和利用这一强大特性。
2483 15
解决lambda中必须为final的方式
解决lambda中必须为final的方式
1070 0
|
前端开发 小程序 Java
【规范】SpringBoot接口返回结果及异常统一处理,这样封装才优雅
本文详细介绍了如何在SpringBoot项目中统一处理接口返回结果及全局异常。首先,通过封装`ResponseResult`类,实现了接口返回结果的规范化,包括状态码、状态信息、返回信息和数据等字段,提供了多种成功和失败的返回方法。其次,利用`@RestControllerAdvice`和`@ExceptionHandler`注解配置全局异常处理,捕获并友好地处理各种异常信息。
8197 1
【规范】SpringBoot接口返回结果及异常统一处理,这样封装才优雅
|
数据采集 前端开发 Java
@ControllerAdvice:你可以没用过,但是不能不了解
`@ControllerAdvice` 是 Spring MVC 中用于定义全局行为的注解,如异常处理、数据绑定和预处理。它从 `@Component` 派生,确保被扫描并纳入容器。`@ExceptionHandler` 用于全局异常处理,提供统一的错误响应。例如,当处理不当的异常时,它能返回友好的错误信息。`@InitBinder` 在数据绑定前对参数进行处理,如格式转换。`@ModelAttribute` 可以用于全局绑定模型属性,如登录用户信息。Spring MVC 通过 `DispatcherServlet` 和 `HandlerAdapter` 在请求处理流程中应用这些全局配置。
1196 3
@ControllerAdvice:你可以没用过,但是不能不了解
|
Java Linux Shell
Linux后台运行jar程序
【7月更文挑战第23天】
836 1
|
开发框架 自然语言处理 Java
如何在Spring Boot中实现动态多语言支持
如何在Spring Boot中实现动态多语言支持
2264 3