Spring MVC Data Binding Extension

Source: Internet
Author: User

After three versions of Spring MVC, the functions have been improved and improved a lot. Especially since 2.5, the Annotation parameter binding has greatly facilitated development, and 3.0 has further improved it. For some special foreground frameworks, the parameters passed to the background are not common request parameters, but the xml format in the request stream. In this case, the parameter binding method inherent in SpringMVC cannot be used. In this case, consider whether it can be extended.

SpringMVC uses AnnotationMethodHandlerAdapter. java by default. You can modify this class for extension. The key points are as follows:

Protected ModelAndView invokeHandlerMethod (HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

ServletHandlerMethodResolver methodResolver = getMethodResolver (handler );

Method handlerMethod = methodResolver. resolveHandlerMethod (request );

ServletHandlerMethodInvoker methodInvoker = new ServletHandlerMethodInvoker (methodResolver );

ServletWebRequest webRequest = new ServletWebRequest (request, response );

ExtendedModelMap implicitModel = new BindingAwareModelMap ();

Object result = methodInvoker. invokeHandlerMethod (handlerMethod, handler, webRequest, implicitModel );

ModelAndView mav = methodInvoker. getModelAndView (handlerMethod, handler. getClass (), result, implicitModel, webRequest); methodInvoker. updateModelAttributes (handler, (mav! = Null? Mav. getModel (): null), implicitModel, webRequest );

Return mav;

}
 

ServletHandlerMethodInvoker. java is an internal class inherited from HandlerMethodInvoker. java and invokeHandlerMethod methods need to be extended. Continue to trace this method and find HandlerMethodInvoker. the key method in this method is resolveHandlerArguments (). The key part is as follows:

If (RequestParam. class. isInstance (paramAnn )){

RequestParam requestParam = (RequestParam) paramAnn;

ParamName = requestParam. value ();

Required = requestParam. required ();

DefaultValue = parsedefavaluvalueattribute (requestParam. defaultValue ());

AnnotationsFound ++;

}

Else if (RequestHeader. class. isInstance (paramAnn )){

RequestHeader requestHeader = (RequestHeader) paramAnn;

HeaderName = requestHeader. value ();

Required = requestHeader. required ();

DefaultValue = parsedefavaluvalueattribute (requestHeader. defaultValue ());

AnnotationsFound ++;

}
 


To add this extension, you need to add your own type, such as RequestParamExt, which is followed by an imitation of the following:

Else if (RequestParamExt. class. isInstance (paramAnn )){

RequestParamExtrequestParam = (RequestParamExt) paramAnn;

ParamName = requestParam. value ();

DefaultValue = parsedefavaluvalueattribute (requestParam. defaultValue ());

MiType = requestParam. type ();

AnnotationsFound ++;

}
 

In

Else if (paramName! = Null ){

Args [I] = resolveRequestParam (paramName, required, defaultValue, methodParam, webRequest, handler );

}
 

Add the extension logic above this method:

If (! RequestParamExt. TYPE_NONE.equals (miType )){

If (null = platformRequest ){

HttpServletRequest request = webRequest. getNativeRequest (HttpServletRequest. class );

PlatformRequest = new PlatformRequest (HttpServletRequest) request, "UTF-8 ");

PlatformRequest. receiveData ();

}

If (RequestParamExt. TYPE_PLATFORMREQUEST.equals (miType )){

Args [I] = platformRequest;

}

Else if (RequestParamExt. TYPE_STR.equals (miType )){

Args [I] = resolveRequestStrParamExt (platformRequest, methodParam );

} Else {

Args [I] = resolveRequestParamExt (miType, platformRequest, paramName, defaultValue, methodParam, webRequest, handler );

}

}
 

The two resolveRequest * Ext methods are as follows:

Protected Object resolveRequestStrParamExt (PlatformRequest platformRequest, MethodParameter methodParam ){

VariableList inVl = platformRequest. getVariableList ();

String paraName = methodParam. getParameterName ();

Return inVl. getValueAsObject (paraName );

}


Protected Object resolveRequestParamExt (String miType, PlatformRequest platformRequest, String paramName,

String defaultValue, MethodParameter methodParam, NativeWebRequest webRequest, Object handler) throws Exception {

If (StringUtils. isBlank (paramName )){

ParamName = defaultValue;

}

Class <?> ParamType = methodParam. getParameterType ();

DatasetList inDl = platformRequest. getDatasetList ();

VariableList inVl = platformRequest. getVariableList ();

If (RequestParamExt. TYPE_DS.equals (miType) {// key process of binding

Dataset ds = inDl. getDataset (paramName );

Object vo = paramType. newInstance ();

MiPDataBinder dataBinder = new MiPDataBinder (vo, false );

DataBinder. bind (inVl );

Return dataBinder. getTarget ();

}

}
 

An annotation definition is also required: Example:

Package com. company. springext. web. bind. annotation;


Import java. lang. annotation. incluented;

Import java. lang. annotation. ElementType;

Import java. lang. annotation. Retention;

Import java. lang. annotation. RetentionPolicy;

Import java. lang. annotation. Target;


@ Target (ElementType. PARAMETER)

@ Retention (RetentionPolicy. RUNTIME)

@ Brief ented

Public @ interface RequestParamExt {

Public static final String TYPE_NONE = "none ";

Public static final String TYPE_DS = "ds ";

Public static final String TYPE_VL = "vl ";

Public static final String TYPE_STR = "string ";

String type () default TYPE_NONE;

String value () default "";

String defaultValue () default "ds ";

}
 

Finally, modify the Spring Configuration:

<Bean class = "com. company. springext. web. servlet. mvc. annotation. AnnotationMethodHandlerAdapterExt">

</Bean>
 

At this point, Data Binding in custom formats is implemented.


If you need to customize the output in a specific format, you also need to modify the AnnotationMethodHandlerAdapterExt. java class. The key is in the getModelAndView () method. In the following position:

} Else if (AnnotationUtils. findAnnotation (handlerMethod, ResponseBody. class )! = Null ){

HandleResponseBody (returnValue, webRequest );

Return null;

}
 


Add your own extension method:

Else if (AnnotationUtils. findAnnotation (handlerMethod, ResponseBodyExt. class )! = Null ){

ResponseBodyExt bodyMi = AnnotationUtils. findAnnotation (handlerMethod, ResponseBodyExt. class );

HandleResponseBodyExt (returnValue, webRequest, bodyMi );

Return null;

}
 

Define the handleResponseBodyExt method:

Private void handleResponseBodyExt (Object returnValue, ServletWebRequest webRequest, ResponseBodyMI bodyMi) throws Exception {

HttpServletResponse servletResponse = (HttpServletResponse) webRequest. getNativeResponse ();

WriteWithExtConverters (returnValue, servletResponse, bodyMi );

}
 

The writeWithExtConverters () method is as follows:

Private void writeWithExtConverters (Object returnValue, HttpServletResponse response, ResponseBodyMI bodyMi) throws Exception {

ConvertToXML (...);

};
 


The usage is as follows:

@ RequestMapping (value = "/getContractList ")

@ ResponseBodyExt (isCheck = true, resultType = "SQL", sqlColumns = "ID, TUREID ")

Public Page <Contract> getContractList (@ RequestParamExt (value = "ds_search", type = "ds") Contract cp) throws Exception {

Page <Contract> page = method1 ();

Return page;

}
Author: "Garden"

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.