Spring注解之@RestControllerAdvice

摘要:
现在总结一下这个注释的用法。

前言

    前段时间部门搭建新系统,需要出异常后统一接口的返回格式,于是用到了Spring的注解@RestControllerAdvice。现在把此注解的用法总结一下。

用法

    首先定义返回对象ResponseDto

 1 package com.staff.points.common;
 2 
 3 import lombok.Data;
 4 
 5 import java.io.Serializable;
 6 
 7 @Data
 8 public class ResponseDto<T> implements Serializable {
 9     private static final long serialVersionUID = -284719732991678911L;
10 
11     private String code;
12 
13     private String message;
14 
15     private T data;
16 
17     public static <T> ResponseDto<T> assemblingSuccessResponse(T data) {
18         ResponseDto<T> responseDto = new ResponseDto<>();
19         responseDto.setCode(ResponseCodeEnum.SUCCESS.getCode());
20         responseDto.setMessage(ResponseCodeEnum.SUCCESS.getMessage());
21         responseDto.setData(data);
22         return responseDto;
23     }
24 
25     public static <T> ResponseDto<T> assemblingSuccessResponse() {
26         ResponseDto<T> responseDto = new ResponseDto<>();
27         responseDto.setCode(ResponseCodeEnum.SUCCESS.getCode());
28         responseDto.setMessage(ResponseCodeEnum.SUCCESS.getMessage());
29         responseDto.setData(null);
30         return responseDto;
31     }
32 
33     public static <T> ResponseDto<T> assemblingFailureResponse(ResponseCodeEnum data) {
34         ResponseDto<T> responseDto = new ResponseDto<>();
35         responseDto.setCode(data.FAILURE.getCode());
36         responseDto.setMessage(data.FAILURE.getMessage());
37         return responseDto;
38     }
39 
40     public static <T> ResponseDto<T> assemblingFailureResponse() {
41         ResponseDto<T> responseDto = new ResponseDto<>();
42         responseDto.setCode(ResponseCodeEnum.FAILURE.getCode());
43         responseDto.setMessage(ResponseCodeEnum.FAILURE.getMessage());
44         return responseDto;
45     }
46 }

    然后定义返回码的枚举类,此处只定义了两种,有需要可以往下添加很多。

 1 package com.staff.points.common;
 2 
 3 import lombok.AllArgsConstructor;
 4 import lombok.Getter;
 5 
 6 @AllArgsConstructor
 7 @Getter
 8 public enum ResponseCodeEnum {
 9     SUCCESS("00", "成功"),
10     FAILURE("01", "系统异常");
11 
12 
13     private String code;
14     private String message;
15 }

    下面是自定义的异常类

 1 package com.staff.points.common;
 2 
 3 import lombok.Data;
 4 
 5 @Data
 6 public class StaffPointsException extends RuntimeException{
 7     private String code;
 8     private String message;
 9     public StaffPointsException () {}
10 
11     public StaffPointsException (Exception e) {
12         super(e);
13     }
14 
15     public StaffPointsException (String code, String message) {
16         super(message);
17         this.code = code;
18         this.message = message;
19     }
20 
21     public StaffPointsException (ResponseCodeEnum codeEnum) {
22         super(codeEnum.getMessage());
23         this.code = codeEnum.getCode();
24         this.message = codeEnum.getMessage();
25     }
26 }

    然后是关键的@RestControllerAdvice修饰的类

 1 package com.staff.points.exception;
 2 
 3 import com.staff.points.common.ResponseCodeEnum;
 4 import com.staff.points.common.ResponseDto;
 5 import com.staff.points.common.StaffPointsException;
 6 import org.slf4j.Logger;
 7 import org.slf4j.LoggerFactory;
 8 import org.springframework.stereotype.Component;
 9 import org.springframework.web.bind.annotation.ExceptionHandler;
10 import org.springframework.web.bind.annotation.RestControllerAdvice;
11 
12 @RestControllerAdvice
13 @Component
14 public class UnifyExceptionHandler {
15     private Logger logger = LoggerFactory.getLogger(UnifyExceptionHandler.class);
16 
17     @ExceptionHandler(Exception.class)
18     public ResponseDto handlerCommonException (Exception e) {
19         ResponseDto responseDto = new ResponseDto<>();
20         responseDto.setCode(ResponseCodeEnum.FAILURE.getCode());
21         responseDto.setMessage(ResponseCodeEnum.FAILURE.getMessage());
22         logger.info("UnifyExceptionHandler.handlerCommonException exception:" + e);
23         return responseDto;
24     }
25     // 报StaffPointException时,对其进行拦截并处理的方法
26     @ExceptionHandler(StaffPointsException.class)
27     public ResponseDto handlerCustomizeException (StaffPointsException e) {
28         ResponseDto responseDto = new ResponseDto<>();
29         responseDto.setCode(e.getCode());
30         responseDto.setMessage(e.getMessage());
31         logger.info("UnifyExceptionHandler.handlerCustomizeException StaffPointsException:" + e);
32         return responseDto;
33     }
34 }

    运行代码时,如果出现了StaffPointException,那么就会被拦截进入第27行的方法(就是说可以自由的在业务代码里往外throw自定义异常了);如果出现了其他的异常,则进入18行的方法,统一返回。

验证一下,在代码里造一个NPE异常时,返回结果:

1 {
2   "code": "01",
3   "message": "系统异常",
4   "data": null
5 }

    造一个StaffPointsException异常时,返回结果:

1 {
2   "code": "99",
3   "message": "自定义业务异常",
4   "data": null
5 }

    它的作用原理,大体是先在spring初始化时将类扫描进容器,出异常后,在DispatcherServlet类的doDispatch方法中调用了对异常的拦截处理。

小结

    看@RestControllerAdvice源码可以知道,它就是@ControllerAdvice和@ResponseBody的合并。此注解通过对异常的拦截实现的统一异常返回处理,如果大家在项目中有类似的需求,不妨试一下,好用又方便。

免责声明:文章转载自《Spring注解之@RestControllerAdvice》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇[译]在启用浏览器功能的INFOPATH表单中实现基于SQL SERVER的多级联动的下拉式列表容器虚拟化网络和Docker容器网络(转载)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

SpringBoot入门篇

一    什么是springboot Spring官网:http://spring.io/projects SpringBoot是Spring项目中的一个子工程,与我们所熟知的Spring-framework 同属于spring的产品: Springboot不是什么真正意义上的新框架,就像maven整合了所有的jar包,spring boot整合了所有常...

SpringMVC基础知识

SpringMVC SpringMVC简介: SpringMVC是一个表示层框架,搭建真实环境 SpringMVC的使用方法:注解和配置。(注解为主) SpringMVC是Spring3.x的一个模块,其实就是用MVC提供的表示层框架。 SpringMVC对视图组件没有必然要求,不一定要使用jsp,struts1,struts2规定了只能用jsp。 Spr...

技术问答集录(四)(spring aop Lombok 原理)

问题: Spring AOP和Lombok是什么原理? 如何实现一个自定义的Spring Boot Starter? 1.Spring AOP和Lombok是什么原理? Spring AOP原理 ①AOP: AOP 实现的关键就在于 AOP 框架自动创建的 AOP 代理,AOP 代理则可分为静态代理和动态代理两大类,其中静态代理是指使用 AOP 框架提...

Spring学习笔记(14)——SpEL

是什么 Spring表达式语言全称为“Spring Expression Language”,缩写为“SpEL”,类似于Struts2x中使用的OGNL表达式语言,能在运行时构建复杂表达式、存取对象图属性、对象方法调用等等,并能与Spring功能完美整合。 表达式语言给静态Java语言增加了动态功能。 SpEL是单独模块,只依赖于core模块,...

spring2.0-2.5-3.0变化[转]

spring2.0-2.5-3.0变化[转] 博客分类: JAVA spring   2.5的新特性Spring2.5rc1发布了,一直想知道它葫芦里卖什么药,以下是文档里的change.log 1. JDK版本: JDK至少要1.4.2以上,如果仍然打算使用1.3的话就请用2.0.6/2.0.7版本吧。 2. Jar包:SpringMVC 不...

Spring Boot + Spring Cloud 实现权限管理系统 权限控制(Shiro 注解)

技术背景 当前,我们基于导航菜单的显示和操作按钮的禁用状态,实现了页面可见性和操作可用性的权限验证,或者叫访问控制。但这仅限于页面的显示和操作,我们的后台接口还是没有进行权限的验证,只要知道了后台的接口信息,就可以直接通过swagger或自行发送ajax请求成功调用后台接口,这是非常危险的。接下来,我们就基于Shiro的注解式权限控制方案,来给我们的后台接...