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

  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. discuz 模板中使用方法和语言标签

    一.如何调用方法? 关于模板中eval的使用{eval php 语句} 比如:<!--{eval echo "Hello World!"}--> 例如在discuz的手 ...

  2. Azkaban实战,Command类型单一job示例,任务中执行外部shell脚本,Command类型多job工作flow,HDFS操作任务,MapReduce任务,HIVE任务

    本文转载自:https://blog.csdn.net/tototuzuoquan/article/details/73251616 1.Azkaban实战 Azkaba内置的任务类型支持comman ...

  3. windows 7 安装时提示:安装程序无法创建新的系统分区

    window7纯净通过U盘引导进行硬盘安装: 系统提示"安装程序无法创建新的系统分区,也无法定位现有分区",导致安装无法进行. 解决办法1: 一种非常简单的办法,首先需要将C盘重新 ...

  4. 未来-区块链-Micron:区块链永远不会忘记:内存对这项革命性技术的推动作用

    ylbtech-未来-区块链-Micron:区块链永远不会忘记:内存对这项革命性技术的推动作用 1.返回顶部 1. 俗话说,大象永远不会忘记.区块链亦是如此. 内存是区块链的核心,它是一种以关键方式构 ...

  5. selenium 添加动态隧道代理

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

  6. windows2008 apache2.4 tomcat-7多域名绑定环境配置

    =====================软件清单Apache2.4.33apache-tomcat-7.0.85===================== 1.安装apache    1.1下载ap ...

  7. JS面试Q&A(续2): Rest parameter,Arrow function 等

    rest parameter 和 Destructuring assignment. function fun1(...theArgs) { console.log(theArgs.length);} ...

  8. .net core下载文件

    上传的文件是在wwwroot下  通过保存的路径跟文件名称完成下载 public IActionResult DownloadFile() { var filePath = "/Upload ...

  9. bootstrapvalidator的简单校验【必填校验、长度校验、是否存在校验(remote)】

    需求:输入框的"供应商编码"不能为空而且不能与数据库重复,供应商名称不能为空. 解决: 1.input如下 <input id="ssupplierNo" ...

  10. OO第一单元(求导)单元总结

    OO第一单元(求导)单元总结 这是我们oo课程的第一个单元,也是意在让我们接触了解掌握oo思想的一个单元,这个单元的作业以求导为主题,从一开始的加减多项式求导再到最后的嵌套多项式求导,难度逐渐提高,编 ...