当前位置: 首页 > 后端技术 > Java

还要在Controller接口中统一写返回的JSON结构?快来试试@ControllerAdvice注解

时间:2023-04-02 00:55:53 Java

众所周知,现在的前后端交互基本都是采用标准的JSON结构{"code":200,"message":"success","data":null}不知道@ControllerAdvice接口返回之前的注释像这样@GetMapping("/")publicBaseResponsetest(){StringtestMsg=testService.getTestMsg();返回BaseResponse.ok(testMsg);}@GetMapping("/findUser/{id}")publicBaseResponsefindUserById(@PathVariable("id")LonguserId){Useruser=testService.findUserById(userId);返回BaseResponse.ok(用户);}BaseResponse是统一返回的对象@Data@EqualsAndHashCode@NoArgsConstructorpublicclassBaseResponse{/***Responsecode*/privateIntegercode;/***响应信息*/privateStringmsg;/***响应数据*/私有T数据;publicBaseResponse(Integerstatus,Stringmsg,Tdata){this.code=status;this.msg=味精;这个。数据=数据;}@NonNullpublicstaticBaseResponseok(@NullableStringmsg,@NullableTdata){returnnewBaseResponse<>(HttpStatus.OK.value(),msg,data);}}@NonNullpublicstaticBaseResponseok(@NullableStringmsg){returnok(msg,null);}publicstaticBaseResponseok(@NullableTdata){returnnewBaseResponse<>(HttpStatus.OK.value(),HttpStatus.OK.getReasonPhrase(),data);}}知道@ControllerAdvice注解后,接口返回是这样的@GetMapping("/")publicStringtest(){StringtestMsg=testService.getTestMsg();返回测试消息;}@GetMapping("/findUser/{id}")publicUserfindUserById(@PathVariable("id")LonguserId){Useruser=testService.findUserById(userId);返回用户;}使用@ControllerAdvice注解拦截Controller层的所有接口,然后使用BaseResponse进行统一封装,这样就不需要在每个Controller接口都使用BaseResponse来封装@ControllerAdvice("com.test.controller")公共类CommonResultControllerAdvice实现ResponseBodyAdvice{@Overridepublicbooleansupports(MethodParameterreturnType,@NonNullClass>converterType){returnAbstractJackson2HttpMessageConverter.class.isAssignableFrom(converterType);}@Override@NonNullpublicfinalObjectbeforeBodyWrite(@NullableObjectbody,@NonNullMethodParameterreturnType,@NonNullMediaTypecontentType,@NonNullClass>converterType,@NonNullServerHttpRequest请求,@NonNullServerHttpResponse响应){MappingJacksonValuecontainer=getOrCreateContainer(body);//containbody之前永远不会为nullBodyWriteInternal(容器);返回容器;}/***将主体包裹在{@linkMappingJacksonValue}值容器中(用于提供*额外的序列化指令)或者如果已经包裹则简单地转换它。*/privateMappingJacksonValuegetOrCreateContainer(Objectbody){returnbodyinstanceofMappingJacksonValue?(MappingJacksonValue)body:newMappingJacksonValue(body);}privatevoidbeforeBodyWriteInternal(MappingJacksonValuebodyContainer){//获取返回主体对象returnBody=bodyContainer.getValue();BaseResponsebaseResponse=BaseResponse.ok(returnBody);bodyContainer.setValue(baseResponse);}}去掉StringHttpMessageConvert消息转换器,否则Controller层接口不会将返回的String转换成统一的返回对象。BaseResponse@ConfigurationpublicclassWebConfigextendsWebMvcConfigurationSupport{@OverridepublicvoidextendMessageConverters(List>converters){converters.removeIf(c->cinstanceofStringHttpMessageConverter);}}}