You may have this requirement to have a two-time package for your controller return value,
As follows: Code is the result code (1, Success, 0, failure, 2, not logged in ...). ), data is carried
{"Code": "1", "data": {"name": "Xiaoming", "Age": "30"}}
Use the following in your code, add a custom annotation responsedata, and automatically encapsulate the data in the format above
@Controller Public class Core { @ResponseData @RequestMapping ("/data") public map<string, Object > data () { Mapnew hashmap<>(); Res.put ("name", "Xiaoming"); Res.put ("Age", "the"); return res; }}
Handlermethodreturnvaluehandler
The name of this interface is a bit strange, the processor that handles the function return value? Let's call him back to the value processor.
This is an interface for handling controller return values, such as the responsebody annotations we are familiar with, which can be implemented simply using the following code.
The disadvantage of this aspect is that if the function does not return a value, the code of the interface will not be executed, and if the return value is often passed using Modelandview, the interface will feel unaccustomed.
Importcom.alibaba.druid.support.json.JSONUtils;ImportOrg.springframework.core.MethodParameter;ImportOrg.springframework.web.bind.annotation.ResponseBody;Importorg.springframework.web.context.request.NativeWebRequest;ImportOrg.springframework.web.method.support.HandlerMethodReturnValueHandler;ImportOrg.springframework.web.method.support.ModelAndViewContainer;ImportJavax.servlet.http.HttpServletResponse;/*** Created by 12614 on 2018/5/11.*/ Public classExampleImplementsHandlermethodreturnvaluehandler {@Override Public BooleanSupportsreturntype (Methodparameter methodparameter) {returnMethodparameter.hasmethodannotation (responsebody.class); } @Override Public voidHandlereturnvalue (Object o, Methodparameter methodparameter, Modelandviewcontainer Modelandviewcontainer,
Nativewebrequest nativewebrequest)throwsException {//TODO. Setrequesthandled (True) indicates that this function can handle the request without having to give it to another code to handle//e.g.Modelandviewcontainer.setrequesthandled (true); Nativewebrequest. Getnativeresponse (HttpServletResponse.class). Getwriter (). Write (Jsonutils.tojsonstring (o)); }}Spring Configuration
< Mvc:annotation-driven > < mvc:return-value-handlers > < class= "xxxx Full class name"></bean> </mvc:return-value-handlers> </Mvc:annotation-driven >
Springboot Configuration
Because under Springboot, the default Responsebody processing class is Handlermethodreturnvaluehandler, which has a higher priority than our newly added implementation class,
In webmvcconfigureradapter configuration Handlermethodreturnvaluehandler, the code actually does not take effect,
If you want to add an additional return value handler, you need to transform the default processing class (if you replace the default processing class directly, but the original responsebody processing logic will be faulted).
Importorg.springframework.context.annotation.Configuration;ImportOrg.springframework.web.method.support.HandlerMethodReturnValueHandler;ImportOrg.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;Importjava.util.List;/*** Created by 12614 on 2018/5/11.*/@Configuration Public classApplicationconfigurerextendsWebmvcconfigureradapter {@Override Public voidAddreturnvaluehandlers (listreturnvaluehandlers) { Super. Addreturnvaluehandlers (returnvaluehandlers); Returnvaluehandlers.add (NewExample ()); }}
Requestresponsebodymethodprocessor is the default handler for Responsebody, and if it's not very clear what it does, you don't want to change any of the default processing logic,
You can create a static proxy class with the following code:
ImportOrg.springframework.core.MethodParameter;ImportOrg.springframework.web.bind.annotation.ResponseBody;Importorg.springframework.web.bind.support.WebDataBinderFactory;Importorg.springframework.web.context.request.NativeWebRequest;ImportOrg.springframework.web.method.support.HandlerMethodReturnValueHandler;ImportOrg.springframework.web.method.support.ModelAndViewContainer;ImportOrg.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor;ImportJava.util.HashMap;ImportJava.util.Map;/*** Created by 12614 on 2018/5/11.*/ Public classTestreturnvaluehandlerImplementsHandlermethodreturnvaluehandler {Privaterequestresponsebodymethodprocessor Target; PublicTestreturnvaluehandler (requestresponsebodymethodprocessor target) { This. target =Target; } @Override Public BooleanSupportsreturntype (Methodparameter methodparameter) {System.out.println ("Testreturnvaluehandler:supportsreturntype"); //I added a custom annotation responsedata, do not know how to write can directly copy responsebody source code returnMethodparameter.hasmethodannotation (ResponseData.class)||methodparameter.hasmethodannotation (responsebody.class); } @Override Public voidHandlereturnvalue (Object o, Methodparameter methodparameter, Modelandviewcontainer m Odelandviewcontainer, Nativewebrequest nativewebrequest)throwsException {System.out.println ("Testreturnvaluehandler:handlereturnvalue"); if(Methodparameter.hasmethodannotation (ResponseData.class)){ //If my custom annotations are used in the controller, the return value is encapsulatedmap<string,object> res =NewHashmap<>(); Res.put ("Code", "1"); Res.put ("Data", O); Target.handlereturnvalue (res,methodparameter,modelandviewcontainer,nativewebrequest); } Else{target.handlereturnvalue (o,methodparameter,modelandviewcontainer,nativewebrequest); } } PublicObject resolveargument (methodparameter parameter, Modelandviewcontainer Mavcontainer, Nativewebrequest webRequest, webdatabinderfactory binderfactory)throwsException {returntarget.resolveargument (parameter, Mavcontainer, WebRequest, binderfactory); }}
To replace the default implementation class for Handlermethodreturnvaluehandler in Springboot, you need to find the appropriate facets in spring,
Initializingbean after executing all the property setting methods (that is, setxxx) will be automatically called, just to meet our needs, in Initializingbean to edit our code, the code is as follows:
ImportOrg.springframework.beans.factory.InitializingBean;Importorg.springframework.beans.factory.annotation.Autowired;Importorg.springframework.context.annotation.Configuration;ImportOrg.springframework.web.method.support.HandlerMethodReturnValueHandler;ImportOrg.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;ImportOrg.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor;Importjava.util.ArrayList;Importjava.util.List;/*** Initialize Facets * * Created by 12614 on 2018/5/11.*/@Configuration Public classInitializingadviceImplementsInitializingbean {@AutowiredPrivateRequestmappinghandleradapter Adapter; @Override Public voidAfterpropertiesset ()throwsException {List<HandlerMethodReturnValueHandler> returnvaluehandlers =adapter.getreturnvaluehandlers (); List<HandlerMethodReturnValueHandler> handlers =NewArrayList (returnvaluehandlers); This. Decoratehandlers (handlers); Adapter.setreturnvaluehandlers (handlers); } Private voidDecoratehandlers (listhandlers) { for(Handlermethodreturnvaluehandler handler:handlers) {if(Handlerinstanceofrequestresponsebodymethodprocessor) {Testreturnvaluehandler Decorator=NewTestreturnvaluehandler ((requestresponsebodymethodprocessor) handler); intindex =Handlers.indexof (handler); Handlers.set (index, decorator); Break; } } }}
Springboot (Thu) Handlermethodreturnvaluehandler