Bootstrap

字节跳动面试官:SpringBoot统一接口返回和全局异常处理怎么玩?

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
img

正文

/**

  • 成功

*/

public static Result success(T data) {

Result result = new Result();

result.setCode(ResultMsgEnum.SUCCESS.getCode());

result.setMessage(ResultMsgEnum.SUCCESS.getMessage());

result.setData(data);

return result;

}

/**

  • 失败

*/

public static Result 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来包装返回信息,会新增很多重复代码,显得不够优雅,甚至都不好意思拿出去显摆。 肯定会有一种方式能够再一次提高代码逼格,实现最优解。

字节跳动面试官:SpringBoot统一接口返回和全局异常处理怎么玩?

三、进阶用法

======

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

3.1 类介绍

=======

3.1类介绍

======

3.1 类介绍

=======

  • ResponseBodyAdvice: 该接口是SpringMVC 4.1提供的,它允许在 执行 @ResponseBody后自定义返回数据,用来封装统一数据格式返回;

  • @RestControllerAdvice: 该注解是对Controller进行增强的,可以全局捕获抛出的异常。

3.2 用法说明

========

  • 新建ResponseAdvice类;

  • 实现ResponseBodyAdvice接口,实现supports、beforeBodyWrite方法;

  • 该类用于统一封装controller中接口的返回结果。

@RestControllerAdvice

public class ResponseAdvice implements ResponseBodyAdvice {

@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注解,该注解的作用花哥上面已经介绍过,就不再唠叨了。

@RestControllerAdvice

public class CustomerExceptionHandler {

}

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

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

@RestControllerAdvice

@Slf4j

public 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中增加一条判断即可。

@RestControllerAdvice

public class ResponseAdvice implements ResponseBodyAdvice {

@Autowired

private ObjectMapper objectMapper;

总结

其他的内容都可以按照路线图里面整理出来的知识点逐一去熟悉,学习,消化,不建议你去看书学习,最好是多看一些视频,把不懂地方反复看,学习了一节视频内容第二天一定要去复习,并总结成思维导图,形成树状知识网络结构,方便日后复习。

这里还有一份很不错的《Java基础核心总结笔记》,特意跟大家分享出来

目录:

部分内容截图:

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
方便日后复习。

这里还有一份很不错的《Java基础核心总结笔记》,特意跟大家分享出来

目录:

[外链图片转存中…(img-g2tCJxvi-1713464551943)]

部分内容截图:

[外链图片转存中…(img-vwGS8aO7-1713464551944)]

[外链图片转存中…(img-xgjKt3O8-1713464551945)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-Qycc7ntC-1713464551946)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

;