1、前言
作为一个小白Java工程师,我或多或少会对程序代码重构和优化,
比较典型的就是我会抗拒老项目接口里的map入参,鬼知道里面是要哪些数据,里面又有哪些数据不可为空,就要一个个去看,代码里用if非空判断以及取值map.get啥啥啥的地方,而且更无语的还是那些老代码都比我岁数还大,都是伴随着项目出生的,所以基本都是common包里的公共方法,不可能轻易重构,改了还不如拉个springboot开源脚手架从0.8做起,做个新项目。
看来是扯远了,我本想说的可不是接口入参的优化,我想记录的是接口开发中一种常见的场景- 对接。
一般情况下,如果项目经理说,我们提供接口,客户系统调用,那么我们很快就会从钉钉收到经理发送来的接口文档。一般来说,这些接口没啥新功能,就是那些平时那些玩意,不过要以客户的格式和客户的其他要求定制接口,例如字段名不一样啦,一次返回一个list了,或者xxl-job搞个定时任务,按客户的地址每天定时给他们推送数据。然而,接口文档最后一页中往往会存在错误码和错误提示,这也就应该明白了,起码要写个枚举,为了数据返回统一,你还要自定义返回类,和自定义异常。
以下是正文
1、背景
项目中,通常会统一接口返回数据格式,例如ResponseEntity,或自定义R类,
通常格式以 {code,msg,data,time}为标准。返回数据使用方法是 .ok() .error()或者success/
Fail()等等。但是一旦我的接口异常了,返回的就是异常堆栈,http状态码500等。而不是我们想要的统一格式了。
再举个例子,我们平常开发任务里,一定有对接客户系统,这时候,我们需要与对方协定对接方式,一般为restful的话,就需要对方提供一个接口文档,由我们实现接口,里面往往预定义了一些错误状态码,我们的接口实现需要根据具体错误,去返回给客户对应的状态码,比如, code:999,msg:用户不存在。 也就是我们接口要这样写:
If(UserService.getUserById(id)==null){
Log.error(id+“用户不存在”);
return R.error(999,’’ 用户不存在‘’);
}
然而这样写并不可取,因为异常时刻有可能发生,而且这样写也毫无封装,很明显这里算作一个业务”异常”,所以要主动抛出异常。而前面说过,抛出异常就不返回统一格式了,所以要用springboot注解@RestControllerAdvice,捕获拦截异常,在抛出异常时,返回你想要的格式。例如R类。
2、R类 统一返回格式
首先,明确一个点,返回类需要做的事情。
总结起来,无非是两件事,
一是格式,做到 code、msg、data、以及可有可无的time
二是静态方法,提供快捷生成返回对象方法,一般你需要定义以下几种方法
01: success() fail() 空参
02: success(data) 只带data
03: fail 带code、msg,不带data
04: success 啥都带
解读: 一般来说,异常枚举常量里都是code和msg在一起的,所以返回方法里,对于msg有两种选择,一种是使用枚举里的,那就省事了,二是使用枚举的,但msg我要自己覆盖一下,重写一个报错原因,最经典的就是因为我要把userId传进msg里。不满足”用户不存在”,写上”用户 90527”不存在。
具体代码如下
/*
- Copyright 2019-2029 geekidea(https://github.com/geekidea)
- Licensed under the Apache License, Version 2.0 (the “License”);
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
http://www.apache.org/licenses/