详解SpringBoot定制@ResponseBody注解返回的Json格式
1、引言
在SpringMVC的使用中,后端与前端的交互一般是使用Json格式进行数据传输,SpringMVC的@ResponseBody注解可以很好的帮助我们进行转换,但是后端返回数据给前端往往都有约定固定的格式,这时候我们在后端返回的时候都要组拼成固定的格式,每次重复的操作非常麻烦。
2、SpringMVC对@ResponseBody的处理
SpringMVC处理@ResponseBody注解声明的Controller是使用默认的.RequestResponseBodyMethodProcessor类来实现,RequestResponseBodyMethodProcessor类实现了HandlerMethodReturnValueHandler接口并实现了接口中的supportsReturnType()和handleReturnValue()方法。
/*
*Copyright2002-2017theoriginalauthororauthors.
*
*LicensedundertheApacheLicense,Version2.0(the"License");
*youmaynotusethisfileexceptincompliancewiththeLicense.
*YoumayobtainacopyoftheLicenseat
*
*http://www.apache.org/licenses/LICENSE-2.0
*
*Unlessrequiredbyapplicablelaworagreedtoinwriting,software
*distributedundertheLicenseisdistributedonan"ASIS"BASIS,
*WITHOUTWARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied.
*SeetheLicenseforthespecificlanguagegoverningpermissionsand
*limitationsundertheLicense.
*/
packageorg.springframework.web.method.support;
importorg.springframework.core.MethodParameter;
importorg.springframework.lang.Nullable;
importorg.springframework.web.context.request.NativeWebRequest;
/**
*Strategyinterfacetohandlethevaluereturnedfromtheinvocationofa
*handlermethod.
*
*@authorArjenPoutsma
*@since3.1
*@seeHandlerMethodArgumentResolver
*/
publicinterfaceHandlerMethodReturnValueHandler{
/**
*Whetherthegiven{@linkplainMethodParametermethodreturntype}is
*supportedbythishandler.
*@paramreturnTypethemethodreturntypetocheck
*@return{@codetrue}ifthishandlersupportsthesuppliedreturntype;
*{@codefalse}otherwise
*/
booleansupportsReturnType(MethodParameterreturnType);
/**
*Handlethegivenreturnvaluebyaddingattributestothemodeland
*settingavieworsettingthe
*{@linkModelAndViewContainer#setRequestHandled}flagto{@codetrue}
*toindicatetheresponsehasbeenhandleddirectly.
*@paramreturnValuethevaluereturnedfromthehandlermethod
*@paramreturnTypethetypeofthereturnvalue.Thistypemusthave
*previouslybeenpassedto{@link#supportsReturnType}whichmust
*havereturned{@codetrue}.
*@parammavContainertheModelAndViewContainerforthecurrentrequest
*@paramwebRequestthecurrentrequest
*@throwsExceptionifthereturnvaluehandlingresultsinanerror
*/
voidhandleReturnValue(@NullableObjectreturnValue,MethodParameterreturnType,
ModelAndViewContainermavContainer,NativeWebRequestwebRequest)throwsException;
}
3、实现思路
知道@ResponseBody是由RequestResponseBodyMethodProcessor进行处理的,这时候我们可以自己定义一个处理返回数据的Handler来实现我们的定制化Json格式数据返回,但是如果直接把我们定制的Handler加入到SpringMVC的ReturnValueHandlers中,因为我们定制的Handler在RequestResponseBodyMethodProcessor之后,所以我们定制的Handler还是不会生效,这时候我们可以想办法把RequestResponseBodyMethodProcessor替换成我们定制的Handler。
4、代码实现
4.1、定制Json返回格式实体
packagecom.autumn.template;
importlombok.AllArgsConstructor;
importlombok.Getter;
importlombok.NoArgsConstructor;
importlombok.Setter;
importlombok.experimental.Accessors;
/**
*JSON信息交互对象模板
*@AuthorAutumn、
*@Date2019/4/823:46
*@Description
*/
@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain=true)
publicclassResultimplementsBaseBean{
......(这里只展示一些必要字段)
/**响应码*/
privateIntegercode;
/**响应信息*/
privateStringmessage;
/**数据*/
privateObjectdata;
/**请求地址*/
privateStringurl;
......
}
4.2、定义定制Json返回格式Handler
packagecom.autumn.component.handler;
importcom.autumn.template.Result;
importorg.springframework.core.MethodParameter;
importorg.springframework.lang.Nullable;
importorg.springframework.web.context.request.NativeWebRequest;
importorg.springframework.web.method.support.HandlerMethodReturnValueHandler;
importorg.springframework.web.method.support.ModelAndViewContainer;
/**
*统一处理ResponseBody数据格式
*@Author:Autumn、
*@Date:2019/4/2423:59
*@Description:
**/
publicclassResultWarpReturnValueHandlerimplementsHandlerMethodReturnValueHandler{
privatefinalHandlerMethodReturnValueHandlerdelegate;
/**委托*/
publicResultWarpReturnValueHandler(HandlerMethodReturnValueHandlerdelegate){
this.delegate=delegate;
}
/**
*判断返回类型是否需要转成字符串返回
*@paramreturnType方法返回类型
*@return需要转换返回true,否则返回false
*/
@Override
publicbooleansupportsReturnType(MethodParameterreturnType){
returndelegate.supportsReturnType(returnType);
}
/**
*返回值转换
*/
@Override
publicvoidhandleReturnValue(@NullableObjectreturnValue,MethodParameterreturnType,ModelAndViewContainermavContainer,NativeWebRequestwebRequest)throwsException{
//委托SpringMVC默认的RequestResponseBodyMethodProcessor进行序列化
delegate.handleReturnValue(returnValueinstanceofResult?returnValue:Result.succeed(returnValue),returnType,mavContainer,webRequest);
}
}
4.3、替换默认的RequestResponseBodyMethodProcessor
packagecom.autumn.config;
importcom.autumn.component.handler.ResultWarpReturnValueHandler;
importorg.springframework.beans.factory.InitializingBean;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.cache.annotation.EnableCaching;
importorg.springframework.context.annotation.Configuration;
importorg.springframework.web.method.support.HandlerMethodReturnValueHandler;
importorg.springframework.web.servlet.config.annotation.WebMvcConfigurer;
importorg.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
importorg.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor;
importjava.util.ArrayList;
importjava.util.List;
importlombok.extern.slf4j.Slf4j;
/**
*替换默认的RequestResponseBodyMethodProcessor
*@AuthorAutumn、
*@Date2019/4/823:46
*@Description
*/
@Slf4j
@Configuration
@EnableCaching
publicclassApplicationContextimplementsWebMvcConfigurer,InitializingBean{
@Autowired(required=false)
privateRequestMappingHandlerAdapteradapter;
@Override
publicvoidafterPropertiesSet()throwsException{
//获取SpringMvc的ReturnValueHandlers
ListreturnValueHandlers=adapter.getReturnValueHandlers();
//新建一个List来保存替换后的Handler的List
Listhandlers=newArrayList<>(returnValueHandlers);
//循环遍历找出RequestResponseBodyMethodProcessor
for(HandlerMethodReturnValueHandlerhandler:handlers){
if(handlerinstanceofRequestResponseBodyMethodProcessor){
//创建定制的Json格式处理Handler
ResultWarpReturnValueHandlerdecorator=newResultWarpReturnValueHandler(handler);
//使用定制的Json格式处理Handler替换原有的RequestResponseBodyMethodProcessor
intindex=handlers.indexOf(handler);
handlers.set(index,decorator);
break;
}
}
//重新设置SpringMVC的ReturnValueHandlers
adapter.setReturnValueHandlers(handlers);
}
}
5、总结
至此完成了定制@ResponseBody注解返回的Json格式,在Controller中返回任何的字符串都可以定制成为我们想要的Json格式。此外SpringMVC还提供了非常多的Handler接口来进行Controller的增强,可以使用此思路对参数等进行定制化。
到此这篇关于详解SpringBoot定制@ResponseBody注解返回的Json格式的文章就介绍到这了,更多相关SpringBoot@ResponseBody返回Json内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!