1。前言目前很多项目都是前后端分离的,前后端会事先约定好返回格式。那么后端应该怎么做才能优雅的返回统一格式呢?下面就请跟着小编一步步实现吧。2、直接返回结果我们来看一个最基本的例子,原封不动的返回结果:@Data@AllArgsConstructor@JsonIgnoreProperties(ignoreUnknown=true)publicclassTestVo{privatestaticfinallongserialVersionUID=1L;@Schema(name="Name")私有字符串名称;@Schema(name="age")privateIntegerage;}@RestController@RequestMapping(value="/test")publicclassTestApi{@GetMapping("/simple")publicTestVosimple(){TestVotestVo=newTestVo(《张三》,30);返回测试Vo;}}returnresult:{"name":"张三","age":30}3.如果和前端妹子开发过,就返回格式约定好格式,例如:{"code":0,"msg":"errormessage","data":实际返回结果}那么我们首先要写一个封装结果类Result。为了封装方便,给这个类增加一个success方法:@Data@JsonInclude(JsonInclude.Include.NON_NULL)publicclassResultimplementsSerializable{privatestaticfinallongserialVersionUID=1L;/***返回编码*/privateIntegercode;/***代码说明*/privateStringmsg;/***业务数据*/私有T数据;/***返回成功的结果对象**@paramdata*@param*@return*/publicstaticResultsuccess(Tdata){Resultresult=newResult();结果.setCode(0);结果.setMsg("成功");结果.setData(数据);返回结果;}}4。微调后台接口代码,返回结果格式统一,将返回值改为Result,泛型为原来的返回值类型:@RestController@RequestMapping(value="/test")publicclassTestApi{@GetMapping("/withResult")publicResultwithResult(){TestVotestVo=newTestVo("张三",30);返回结果.成功(testVo);}}返回结果:{“代码”:0,“消息”:“成功”,“数据”:{"name":"张三","age":30}}至此,返回结果完全符合格式,但是这样的代码不够简洁:每个接口的返回值必须是Result<>,并且在返回的时候使用Result.success()方法封装它。那么,有没有更优雅的方式呢?我们继续往下看:5.切片封装统一格式写注解在实际使用场景中,并不是所有接口都需要统一格式。这里我们使用注解作为开关,根据需要控制接口返回格式。@Target({ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic@interfaceApiResult{Stringvalue()默认"";intsuccessCode()默认0;StringsuccessMsg()默认“成功”;类resultClass()defaultResult.class;}编写ControllerAdvice@ControllerAdvicepublicclassMyResponseBodyAdviceimplementsResponseBodyAdvice{protectedbooleanisStringConverter(ClassconverterType){returnconverterType.equals(StringHttpMessageConverter.class);}protectedbooleanisApiResult(MethodParameterreturnType){returnreturnType.hasMethodAnnotation(ApiResult.class);}@Overridepublicbooleansupports(MethodParameterreturnType,ClassconverterType){return!isStringConverter(converterType)&&isApiResult(returnType);}@OverridepublicObjectbeforeBodyWrite(Objectbody,MethodParameterreturnType,MediaTypeselectedContentType,ClassselectedConverterType,ServerHttpRequestrequest,ServerHttpResponseresponse){//KeyreturnResult.success(body);}}这里要注意一点,在这个advice的supports方法中,返回结果类型必须是非String类型,如果返回结果是String类型,那么需要把结果转成json字符串再返回,并且需要写另一个建议。见证奇迹的时刻到了@ApiResult@GetMapping("/withResultHide")publicTestVowithResultHide(){TestVotestVo=newTestVo("张三",30);returntestVo;}这段代码和开头一样,不返回Result,只是加上@ApiResult注解,我们看看返回结果:{"code":0,"msg":"success","data":{"name":"张三","age":30}}大功告成!以上只是最精简的例子。在实际使用中,还结合了统一异常封装、自定义返回格式等功能。我们注意到@ApiResult注解中有三个参数:successCode、successMsg、resultClass,它们是为自定义返回格式预留的。再来看两种场景:6、自定义返回格式场景一:返回成功时code为200如果个别接口的返回格式与默认格式相同,但要求code等于200表示成功,然后修改successCode参数:@ApiResult(successCode=200,successMsg="ok")@GetMapping("/withResultHide")publicTestVowithResultHide(){TestVotestVo=newTestVo("张三",30);returntestVo;}返回成功后,result中的code和msg变为设置值:{"code":200,"msg":"ok","data":{"name":"张三","age":30}}场景二:自定义返回格式如果某个接口的返回格式不是默认的返回格式,比如约定的返回returnCode,returnDesc,data(对应默认的code,msg,data)。然后需要添加一个返回结果类,比如ReturnResult:@Data@JsonInclude(JsonInclude.Include.NON_NULL)publicclassReturnResultimplementsSerializable{privatestaticfinallongserialVersionUID=1L;/***返回码*/privateStringreturnCode;/***代码说明*/privateStringreturnDesc;/***业务数据*/私有T数据;/***返回成功的结果对象**@paramdata*@param*@return*/publicstaticReturnResultsuccess(Tdata){ReturnResultresult=newReturnResult();结果.setReturnCode(0);result.setReturnDesc("成功");结果.setData(数据);返回结果;}}然后修改接口上@ApiResult注解中的resultClass属性:@ApiResult(resultClass=ReturnResult.class)@GetMapping("/withResultHide")publicTestVowithResultHide(){TestVotestVo=newTestVo("张三",30);returntestVo;}这时候返回的结果就变成了想要的格式:{"returnCode":"0","returnDesc":"success","data":{"name":"ZhangSan","age":30}}总结只要按照上面一步一步的改造,就可以实现统一的返回格式,简洁大方。你在等什么?开始吧~