目前很多项目都是前后端分离,前后端会事先约定好返回格式。那么后端如何做,才能优雅的返回统一格式呢,接下来,请大家跟着我,一步步来实现。
1. 直接返回结果先看一下最基本的例子,直接将结果原封不动返回:
@data@allargsconstructor@jsonignoreproperties(ignoreunknown = true)public class testvo { private static final long serialversionuid = 1l; @schema(name = 姓名) private string name; @schema(name = 年龄) private integer age;}@restcontroller@requestmapping(value = /test)public class testapi { @getmapping(/simple) public testvo simple() { testvo testvo = new testvo(张三, 30); return testvo; }}返回结果:
{ name: 张三, age: 30}2. 约定返回格式假如已经与前端开发妹子约定好了格式,比如:
{ code: 0, msg: 错误信息, data: 实际返回结果}那么我们首先需要编写一个封装结果类result。为了方便封装,在这个类中增加一个success方法:
@data@jsoninclude(jsoninclude.include.non_null)public class result implements serializable { private static final long serialversionuid = 1l; /** * 返回编码 */ private integer code; /** * 编码描述 */ private string msg; /** * 业务数据 */ private t data; /** * 返回成功结果对象 * * @param data * @param * @return */ public static result success(t data) { result result = new result(); result.setcode(0); result.setmsg(success); result.setdata(data); return result; }}3. 返回统一格式结果后台接口代码微调一下,返回值改为result,泛型为原返回值的类型:
@restcontroller@requestmapping(value = /test)public class testapi { @getmapping(/withresult) public result withresult() { testvo testvo = new testvo(张三, 30); return result.success(testvo); }}返回结果:
{ code: 0, msg: success, data: { name: 张三, age: 30 }}至此,返回结果完美符合格式。
但是这样的代码并不算简洁:每个接口的返回值都必须是result,并且return的时候都要用result.success()方法封装一下。
那么,有没有更优雅的方法?我们继续往下看:
4. 切片封装统一格式编写注解实际使用场景中,并不是所有接口都需要统一格式。我们这里使用一个注解作为开关,按需控制接口返回格式。
@target({elementtype.method})@retention(retentionpolicy.runtime)@documentedpublic @interface apiresult { string value() default ; int successcode() default 0; string successmsg() default success; class resultclass() default result.class;}编写controlleradvice@controlleradvicepublic class myresponsebodyadvice implements responsebodyadvice { protected boolean isstringconverter(class convertertype) { return convertertype.equals(stringhttpmessageconverter.class); } protected boolean isapiresult(methodparameter returntype) { return returntype.hasmethodannotation(apiresult.class); } @override public boolean supports(methodparameter returntype, class convertertype) { return !isstringconverter(convertertype) && isapiresult(returntype); } @override public object beforebodywrite(object body, methodparameter returntype, mediatype selectedcontenttype, class selectedconvertertype, serverhttprequest request, serverhttpresponse response) { //关键 return result.success(body); }}这里有一点要 注意 ,这个advice中supports方法中判断返回结果类型必须为非string类型。如果返回结果为string类型,那么result要转为json字符串后再返回,需要再写一个advice。
见证奇迹的时刻到了@apiresult@getmapping(/withresulthide)public testvo withresulthide() { testvo testvo = new testvo(张三, 30); return testvo;}这段代码与最开始一样,并没有返回result,仅仅加上了@apiresult注解,我们看返回结果:
{ code: 0, msg: success, data: { name: 张三, age: 30 }}大功告成!
以上只是最精简的例子,实际使用中还结合了 统一异常封装、自定义返回格式 等功能。我们注意到@apiresult注解中,有三个参数:successcode、successmsg、resultclass,就是为了自定义返回格式预留的,下面再看两个场景:
5. 自定义返回格式场景1:返回成功时code为200如果个别接口的返回格式与默认格式相同,但是要求code等于200时才代表成功,那么修改下successcode参数即可:
@apiresult(successcode = 200, successmsg = ok)@getmapping(/withresulthide)public testvo withresulthide() { testvo testvo = new testvo(张三, 30); return testvo;}返回成功时,结果中的code和msg都变为设置的值:
{ code: 200, msg: ok, data: { name: 张三, age: 30 }}场景2:自定义返回格式如果某个接口的返回格式不是默认的返回格式,比如约定返回returncode、returndesc、data(对应默认的code、msg、data)。那么则需要新增一个返回结果类,比如returnresult:
@data@jsoninclude(jsoninclude.include.non_null)public class returnresult implements serializable { private static final long serialversionuid = 1l; /** * 返回编码 */ private string returncode; /** * 编码描述 */ private string returndesc; /** * 业务数据 */ private t data; /** * 返回成功结果对象 * * @param data * @param * @return */ public static returnresult success(t data) { returnresult result = new returnresult(); result.setreturncode(0); result.setreturndesc(success); result.setdata(data); return result; }}然后修改接口上的@apiresult注解中的resultclass属性
@apiresult(resultclass = returnresult.class)@getmapping(/withresulthide)public testvo withresulthide() { testvo testvo = new testvo(张三, 30); return testvo;}这时,返回结果就变为想要的格式了:
{ returncode: 0, returndesc: success, data: { name: 张三, age: 30 }}小结只要按照上面一步步改造,即可实现统一返回格式,既简洁、又优雅。
电控发动机工作原理_电控发动机的三大组成
AMD提交新专利 保护GPU显存指令不被恶意利用
薄膜表面缺陷在线检测设备介绍
互联网电视的江湖仍旧不太平
美国毅力号已将直升飞机带上火星
让代码变得更简洁的小技巧
住友化学下调LCD光学滤光片和偏光片产能
在人工智能的技术时代可能发生什么
断电应急灯的工作原理与维修
搞大事 北京荣耀终端有限公司成立 特斯拉合肥公司成立
海光 HG3250 这款行业主板可以做行业天花板了
浪涌保护器基础知识分享
人工智能在先进制造业领域的发展潜力
网络切片初期商用面临的关键问题
不同材质PCB板的区别是什么
为什么我们需要测试电容器?如何对电容器放电?
变频器逆变桥及制动回路介绍
多重福利下的电动汽车为何还是难以普及
除了电视市场,笔电与显示器市场也为Mini LED带来商机
如何从时域与频域评估传输线特性介绍S参数