字节跳动面试官SpringBoot统一接口返回和全局异常处理怎么玩?
现在大多数公司项目框架,基本都是属于前后端分离模式,这种模式会涉及到一个前后端对接问题,无论是对前端或者是后台服务,维护一套完善且规范的接口是非常有必要的,这样不仅能够提高对接效率,也可以让我的代码看起来更加简洁优雅。
修改前后最大的区别是我们不用在每个接口单独捕获异常,也不用在每个接口都要组装一遍返回参数,可以参考下面这张对比图:
一、SpringBoot不使用统一返回格式
默认情况下,SpringBoot会有如下三种返回情况。1.1 字符串@GetMapping("/getUserName") public String getUserName(){ return "HuaGe"; }
调用接口返回结果:HuaGe1.2 实体类@GetMapping("/getUserName") public User getUserName(){ return new User("HuaGe",18,"男"); }
调用接口返回结果:{ "name": "HuaGe", "age": "18", "性别": "男", }1.3异常返回@GetMapping("/getUserName") public static String getUserName(){ HashMap hashMap = Maps.newHashMap(); return hashMap.get(0).toString(); }
模拟一个空指针异常,在不做任何异常处理的情况下,可以看下SpringBoot的默认返回结果:{ "timestamp": "2021-08-09T06:56:41.524+00:00", "status": 500, "error": "Internal Server Error", "path": "/sysUser/getUserName" }
对于上面这几种情况,如果整个项目没有定义统一的返回格式,五个后台开发人员定义五种返回格式,这样不仅代码臃肿,前后端对接效率低,而且还会有一些意向不到的情况发生,比如前端直接显示异常详情等,这给用户的体验是非常差的。二、基础玩法
项目中最常见到的是封装一个工具类,类中定义需要返回的字段信息,把需要返回前端的接口信息,通过该类进行封装,这样就可以解决返回格式不统一的现象了。2.1 参数说明code: 状态码,后台可以维护一套统一的状态码;message: 描述信息,接口调用成功/失败的提示信息;data: 返回数据。2.2 流程说明新建Result类public class Result { private int code; private String message; private T data; public Result() {} public Result(int code, String message) { this.code = code; this.message = message; } /** * 成功 */ 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来包装返回信息,会新增很多重复代码,显得不够优雅,甚至都不好意思拿出去显摆。 肯定会有一种方式能够再一次提高代码逼格,实现最优解。
三、进阶用法
基本用法学会后,接下来看点究极版本,主要用到如下两个知识点,用法简单,无论是拿出来教学妹,还是指点小姐姐,都是必备技能。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
犹豫中我还是没选中满意的电纸书产品我算是个重度阅读爱好者,特别是晚上睡觉一定要看会书,才能睡着。从最早的Kindle,到早期的ireader,后面用过博阅,2020年5月买了文石的nova2,一直用到现在,积累了几
微信可以同时实名几个账号,明明白白告诉你要说大家最常用的即时通信服务软件,微信处于垄断地位,而且很多人会有两个微信号,一般是一个工作号,一个私人号。在使用微信过程中,很多功能需要实名认证之后才能使用,比如支付功能。有一两
充电桩安装费用多少钱?私人安装充电桩,一般就安装慢充就可以了,一是价格便宜,一两千元(不含安装费),二是慢充充电有利于保护电池,三是可以利用夜间低谷电价。但问题的关键是小区物业能否允许你安装充电桩,因为
明确!手机这个费用,将取消近日有网友在人民网领导留言板中提问来电显示费用何时能够取消如今进入了5G时代,现在的套餐基本上都是减免来电显示费用,但还是有少部分前期套餐附加的来电显示费用,希望工信部能够在提速降
都说阿里巴巴福利好,为什么有人拿到offer却不愿意去阿里?没有都说的福利好,所以没去为什么地球百分之8人类之,熟悉自己国家语言哈哈哈哈呼呼呼呼就目前来说拿到阿里的offer还是比较优秀的,有大厂的背景很可以的,毕竟牌子带在身边看看好的装备
常用的消息队列一redis消息队列和kafka消息队列的比较1Redis作为消息队列Redis的pubsub模式非常像西式快餐一样,快产快消,全都是因为Redis是使用内存来做存取,所有你生产的
在华为工作是怎样一番体验?你好,我结合我身边的一个案例来说一说吧,我自己并没有在华为工作,是我自己家里面一个哥,他在华为工作,他的工作主要是手机开发。他是计算机硕士专业毕业的,然后当时应聘到了华为做手机开发
新机型,华为Mate50Pro逆袭,华为P50Pro升级版自开年以来,国内各大手机厂商迅速发力,大量骁龙8Gen1机型快速发布,因为有这颗4纳米芯片加持,这些新机的性能都相当优秀。每一款都有超百万的跑分,流畅度相当高。部分机型仍然拥有极高
iPhone14再曝光,苹果为了赚钱太无底线?曾几何时,苹果iPhone那绝对是工业设计和配置创新的双巅峰,再加上独有的iOS系统,让其面对整个安卓阵营也丝毫不虚,销量和热度没有哪一家厂商能够单独对抗。但不知道从什么时候开始,
Python机器学习(五十六)SciPyfftpack(傅里叶变换)SciPy提供了fftpack模块,包含了傅里叶变换的算法实现。傅里叶变换把信号从时域变换到频域,以便对信号进行处理。傅里叶变换在信号与噪声处理图像处理音频信号处理等领域得到了广泛
人是怎么来的之进化与创造和史前文明的想象进化论主张宇宙中最原始的存在,并不是具有精神的事物灵或神,而是具有生能的物质。这生能以进化方式,演进成生元,即细胞这细胞便是万物中一切生命的开始。在西方思想史上,力持进化论观点的是