通常在开发具体项目过程中我们可能会面临如下问题:

  1. 统一所有的json返回结果
  2. 统一处理所有controller中的异常,并且给不同异常不同的返回状态值
  3. 统一对返回的接口做数据校验或者加密,防止篡改

在spring中的处理方式是使用@RestControllerAdvice注解。下面是一个例子,可以将所有的controller中的返回结果,包装成一个CommonResponse。

@RestControllerAdvice
public class CommonResponseDataAdvice implements ResponseBodyAdvice<Object> { @Override
@SuppressWarnings("all")
public boolean supports(MethodParameter methodParameter,
Class<? extends HttpMessageConverter<?>> aClass) { if (methodParameter.getDeclaringClass().isAnnotationPresent(
IgnoreResponseAdvice.class
)) {
return false;
} if (methodParameter.getMethod().isAnnotationPresent(
IgnoreResponseAdvice.class
)) {
return false;
} return true;
} @Nullable
@Override
@SuppressWarnings("all")
public Object beforeBodyWrite(@Nullable Object o,
MethodParameter methodParameter,
MediaType mediaType,
Class<? extends HttpMessageConverter<?>> aClass,
ServerHttpRequest serverHttpRequest,
ServerHttpResponse serverHttpResponse) { CommonResponse<Object> response = new CommonResponse<>(0, "");
if (null == o) {
return response;
} else if (o instanceof CommonResponse) {
response = (CommonResponse<Object>) o;
} else {
response.setData(o);
} return response;
}
}

  上述代码中定义了一个注解IgnoreResponseAdvice,如果controller的类或者方法有这个注解就不做处理。下面这个例子展现的是如何在controller抛出异常的时候,自动包装成为commonRespons。

@RestControllerAdvice
public class GlobalExceptionAdvice { @ExceptionHandler(value = ParamException.class)
public CommonResponse<String> handlerParamException(HttpServletRequest req,
ParamException ex) {
CommonResponse<String> response = new CommonResponse<>(400,
"param error");
response.setData(ex.getMessage());
return response;
}
@ExceptionHandler(value = BusinessException.class)
public CommonResponse<String> handlerBusinessException(HttpServletRequest req,
BusinessException ex) {
CommonResponse<String> response = new CommonResponse<>(500,
"business error");
response.setData(ex.getMessage());
return response;
} @ExceptionHandler(value = SystemException.class)
public CommonResponse<String> handlerSystemException(HttpServletRequest req,
SystemException ex) {
CommonResponse<String> response = new CommonResponse<>(700,
"system error");
response.setData(ex.getMessage());
return response;
}
}

  对比下面的controller能更清楚的明白如何使用。

@RestController
public class IndexController { @RequestMapping("/")
String home() {
return "Hello World!";
}
@IgnoreResponseAdvice
@RequestMapping("/hi")
String hi() {
return "Hello World!";
} @RequestMapping("/param")
String param() throws Exception {
throw new ParamException("参数错误");
} @RequestMapping("/business")
String business() throws Exception {
throw new BusinessException("业务错误");
}
@RequestMapping("/system")
String system() throws Exception {
throw new SystemException("系统错误");
}
}

  详细的代码见 https://gitee.com/dongqihust/arst/tree/master/custom-response

  特别的,这个文章提供了几种其他的解决方案:https://www.baeldung.com/exception-handling-for-rest-with-spring

ARTS打卡计划第一周-Tips-ControllerAdvice的使用的更多相关文章

  1. ARTS打卡计划第一周

    Algorithms: https://leetcode-cn.com/problems/two-sum/ Review: https://www.infoq.cn/article/EafgGJEtq ...

  2. ARTS打卡计划第一周-Share-系统字典模块的设计

    在软件开发的过程,经常有一些类型的字段信息:性别.学历.职级.车辆类别.公司类型.结算类型等.这些字段有2个特征:1是字段可选的类型是有限,2是字段可能会变化,我们把这种字段描述为字段字段.  本篇文 ...

  3. ARTS打卡计划第一周-Review

    本周分享的文章来自于medium的 Testing Best Practices for Java + Spring Apps 这个文章主要讲的是java测试的一些最佳实践 1.避免函数返回void, ...

  4. ARTS打卡计划第一周-Algorithm

    7. Reverse Integer import math class Solution: def reverse(self, x: int) -> int: ret = 0 if x > ...

  5. ARTS打卡计划第二周

    Algorithms: https://leetcode-cn.com/problems/3sum/ 算法是先排序,然后按照两个数和两边逼中,考虑去重. Review: https://www.inf ...

  6. ARTS打卡计划第二周-Review

    本周review的文章是:https://medium.com/@hakibenita/optimizing-django-admin-paginator-53c4eb6bfca3 改篇文章的题目是: ...

  7. ARTS打卡计划第九周

    Algorithms: https://leetcode-cn.com/problems/merge-two-sorted-lists/submissions/ 合并两个链表 Review:  “Pu ...

  8. ARTS打卡计划第二周-Share-使用java注解对方法计时

    现在有这样一种常见,系统中有一个接口,该接口执行的方法忽快忽慢,因此你需要去统计改方法的执行时间.刚开始你的代码可能如下: long start = System.currentTimeMillis( ...

  9. ARTS打卡计划第二周-Tips-mysql-binlog-connector-java的使用

    最近发现一个挺不错的框架mysql-binlog-connector-java,可以实时监控binlog的变化. 首先检查mysql的binlog是否开启,在开启的情况下: 引入依赖 <depe ...

随机推荐

  1. FPGA Asynchronous FIFO设计思路

    FPGA Asynchronous FIFO设计思路 将一个多位宽,且在不停变化的数据从一个时钟域传递到另一个时钟域是比较困难的. 同步FIFO的指针比较好确定,当FIFO counter达到上限值时 ...

  2. ulimit -a

    在linux中执行ulimit -a 即可查询linux相关的参数 用ulimit命令是可以修改这些配置的命令的格式:ulimit [-SHacdefilmnpqrstuvx] [limit] 中间的 ...

  3. hive 的map数和reduce如何确定(转)

    转自博客:https://blog.csdn.net/u013385925/article/details/78245011(没找到原创者,该博客也是转发)   一.    控制hive任务中的map ...

  4. React 生命周期及使用场景

    对比版本:16.4.0 VS 16.3.0 VS 16.2.0 发现最近几次React版本更改比较大,在为17.0的大版本作准备.总结了一下React生命周期函数的变化. 综合对比图如下: 各版本分别 ...

  5. ajax(读取json数据)

    ajax知识点: 语法:$.ajax(路由,请求方式,返回的数据类型,数据参数,回调函数) url: "路由", type:"",默认get请求(get或pos ...

  6. selenium 添加动态隧道代理

    # 无须密码验证方法 chromeOptions = webdriver.ChromeOptions() chromeOptions.add_argument('--proxy-server=http ...

  7. vue 跨域问题

    前段时间做一个vue打包成安卓和IOS的App,遇到了跨域问题,直接拿了之前项目的配置,却不起作用. import org.springframework.context.annotation.Con ...

  8. Centos 7 虚拟机挂载U盘

    本文记录环境为在Windows 7环境下,通过VMware安装Centos 7.2.挂载U盘过程如下,供日后查看,也供各位读者遇到类似问题时参考. 挂载过程及问题排除如下: 1.因为是虚拟机,所以先到 ...

  9. ssh 公钥无秘登录问题

    1. 验证服务启动,网络端口连接正常 可以使用nc,telnet,或者密码模式的ssh来验证 2. 验证ssh client端的配置正确 可以尝试登录另外一台主机, 或者本机自校验 3. 验证ssh ...

  10. Android View添加删除或隐藏显示的默认动画;

    代码中给控件设置Visibility ? VISIBLE : GONE ;时太生硬,用户体验不好:设置一个Android ViewGroup的默认动画很实用: 给需要添加动画的控件或布局的父布局,记住 ...