springboot统一返回结果和异常处理,springboot异步接口响应

  springboot统一返回结果和异常处理,springboot异步接口响应

  00-1010前言1。SpringBoot不使用统一的返回格式1.1使用字符串返回1.2使用实体类返回1.3异常情况下返回2。基本玩法2.1参数描述2.2流程描述3。高级用法3.1类介绍3.2用法描述3.3全局异常处理程序3.4统一返回结果处理类最终版本4。摘要

  00-1010目前大部分公司项目框架基本属于前端分离模式。这种模式会涉及到一个前端对接问题。需要为前端或后端服务维护一套完善、规范的接口,这样既可以提高对接效率,也可以让我的代码看起来更加简洁优雅。

  修改前后最大的区别是,我们不用在每个接口单独捕捉异常,也不用在每个接口组装返回参数。请参考下面的对比图:

  00-1010默认情况下,SpringBoot会有以下三种返回情况。

  

目录
@ get mapping(/get username )公共字符串get username(){ nbsp;nbsp返回“葛花”;}调用接口返回结果:

  葛花

  

前言

@ get mapping(/get username )公共用户get username(){ nbsp;nbsp返回新用户(“葛花”,18,“男性”);}调用接口返回结果:

  { nbsp姓名 : 葛花,nbsp。年龄 : 18 ,nbsp。性别 3360 男性,}

  

一、SpringBoot不使用统一返回格式

@ get mapping(/get username )公共静态字符串get username(){ nbsp;nbspHashMap HashMap=maps . new HashMap();nbspnbsp返回hashMap.get(0)。toString();}模拟一个空指针异常。您可以查看没有任何异常处理的SpringBoot的默认返回结果:

  { timestamp : 2021-08-09t 06:56:41.524 00:00 , status: 500, error: 内部服务器错误,Path 3360 /sys user/get username }对于以上情况,如果没有为整个项目定义统一的返回格式,五个后端开发人员定义五种返回格式,这不仅会导致代码臃肿,前端对接效率低下,还会出现一些意想不到的情况,比如前端直接显示异常细节等。会给用户很差的体验。

  00-1010项目中最常见的就是封装一个工具类,这个工具类定义了要返回的字段信息,通过这个类封装要返回到前端的接口信息,这样就可以解决返回格式不一致的现象。

  00-1010code:状态码,后台可以维护一套统一的状态码;message:描述信息、接口调用成功/失败的提示信息;data:返回数据。

  

1.1 使用字符串返回

新建Result类公共类ResultT { private int code私有字符串消息;私人测试数据;public Result() {}公共结果(int code,String message){ this . code=code;this.message=message}/* * *成功*/公共sta

  tic <T> Result<T> success(T data) { Result<T> result = new Result<T>(); result.setCode(ResultMsgEnum.SUCCESS.getCode()); result.setMessage(ResultMsgEnum.SUCCESS.getMessage()); result.setData(data); return result; } /** * 失败 */ public static <T> Result<T> error(int code, String message) { return new Result(code, message); }}定义返回状态码

  

public enum ResultMsgEnum { SUCCESS(0, "成功"), FAIL(-1, "失败"), AUTH_ERROR(502, "授权失败!"), SERVER_BUSY(503, "服务器正忙,请稍后再试!"), DATABASE_OPERATION_FAILED(504, "数据库操作失败"); private int code; private String message;​ ResultMsgEnum(int code, String message) { this.code = code; this.message = message; } public int getCode() { return this.code; } public String getMessage() { return this.message; }}
使用方式上面两步定义了数据返回格式状态码,接下来就要看下在接口中如何使用了。

  

@GetMapping("/getUserName")public Result getUserName(){ return Result.success("huage");}
调用结果如下,可以看到是我们在Result中定义的参数类型。

  

{ "code": 0, "message": "成功", "data": "huage"}
这样写虽然能够满足日常需求,而且我相信很多小伙伴也是这么用的,但是如果我们有大量的接口,然后在每一个接口中都使用Result.success来包装返回信息,会新增很多重复代码,显得不够优雅,甚至都不好意思拿出去显摆。 肯定会有一种方式能够再一次提高代码逼格,实现最优解。

  

  

三、进阶用法

基本用法学会后,接下来看点究极版本,主要用到如下两个知识点,用法简单,无论是拿出来教学妹,还是指点小姐姐,都是必备技能。

  

  

3.1 类介绍

ResponseBodyAdvice: 该接口是SpringMVC 4.1提供的,它允许在 执行 @ResponseBody后自定义返回数据,用来封装统一数据格式返回;@RestControllerAdvice: 该注解是对Controller进行增强的,可以全局捕获抛出的异常。

  

3.2 用法说明

新建ResponseAdvice类;实现ResponseBodyAdvice接口,实现supportsbeforeBodyWrite方法;该类用于统一封装controller中接口的返回结果。
@RestControllerAdvicepublic class ResponseAdvice implements ResponseBodyAdvice<Object> { @Autowired private ObjectMapper objectMapper;​ /** * 是否开启功能 true:是 */ @Override public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) { return true; }​ /** * 处理返回结果 */ @Override public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) { //处理字符串类型数据 if(o instanceof String){ try { return objectMapper.writeValueAsString(Result.success(o)); } catch (JsonProcessingException e) { e.printStackTrace(); } } return Result.success(o); }}​
我们可以通过getUserName接口测试一下,会发现和直接使用Result返回的结果是一致的。

  不过,细心的小伙伴们肯定注意到了,在ResponseAdvice我们全部使用了Result.success(o)来处理结果,对于error类型的结果未做处理。我们来看下,发生异常情况时,返回结果是什么样呢?继续使用上面HashMap空指针异常的代码,测试结果如下:

  

{ "code": 0, "message": "成功", "data": { "timestamp": "2021-08-09T09:33:26.805+00:00", "status": 405, "error": "Method Not Allowed", "path": "/sysUser/getUserName" }}
虽然格式上没有毛病,但是在code、data字段的具体数据上是不友好或不正确的。不处理好这些事情,会严重影响自己在前端妹妹心中的高大形象的,这是决不能容忍的。

  

  

3.3 全局异常处理器

以前我们遇到异常时,第一时间想到的应该是try..catch..finnal吧,不过这种方式会导致大量代码重复,维护困难,逻辑臃肿等问题,这不是我们想要的结果。

  今天我们要用的全局异常处理方式,用起来是比较简单的。首先新增一个类,增加@RestControllerAdvice注解,该注解的作用花哥上面已经介绍过,就不再唠叨了。

  

@RestControllerAdvicepublic class CustomerExceptionHandler {}
如果我们有想要拦截的异常类型,就新增一个方法,使用@ExceptionHandler注解修饰,注解参数为目标异常类型。

  例如:controller中接口发生Exception异常时,就会进入到Execption方法中进行捕获,将杂乱的异常信息,转换成指定格式后交给ResponseAdvice方法进行统一格式封装并返回给前端小伙伴。

  

@RestControllerAdvice@Slf4jpublic class CustomerExceptionHandler { @ExceptionHandler(AuthException.class) public String ErrorHandler(AuthorizationException e) { log.error("没有通过权限验证!", e); return "没有通过权限验证!"; }​ @ExceptionHandler(Exception.class) public Result Execption(Exception e) { log.error("未知异常!", e); return Result.error(ResultMsgEnum.SERVER_BUSY.getCode(),ResultMsgEnum.SERVER_BUSY.getMessage()); }}
再次调用接口getUserName查看返回结果,会发现还是有一些问题,因为我们在CustomerExceptionHandler中已经将接口返回结果封装成Result类型,而代码执行到统一结果返回类ResponseAdvice时,又会结果再次封装,就出现了如下问题。

  

{ "code": 0, "message": "成功", "data": { "code": 503, "message": "服务器正忙,请稍后再试!", "data": null }}

  

3.4 统一返回结果处理类最终版

解决上述问题非常简单,只要在beforeBodyWrite中增加一条判断即可。

  

@RestControllerAdvicepublic class ResponseAdvice implements ResponseBodyAdvice<Object> { @Autowired private ObjectMapper objectMapper;​ /** * 是否开启功能 true:开启 */ @Override public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) { return true; }​ /** * 处理返回结果 */ @Override public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) { //处理字符串类型数据 if(o instanceof String){ try { return objectMapper.writeValueAsString(Result.success(o)); } catch (JsonProcessingException e) { e.printStackTrace(); } } //返回类型是否已经封装 if(o instanceof Result){ return o; } return Result.success(o); }}
至此,本章的任务就全部讲完,上述代码可以直接引用,不需要其他的配置项,非常推荐引用到自己的项目中。

  

  

四、总结

本章讲解的内容不是很多,主要就两个类的配置,即处理统一返回结果的类ResponseAdvice和异常处理类CustomerExceptionHandler。全文围绕RestControllerAdviceResponseBodyAdvice的使用,通过一步步的迭代,最终构建一套通用的代码代码返回格式,更多关于SpringBoot接口返回异常处理的资料请关注盛行IT其它相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: