Spring MVC经过三个版本,功能已经改进和完善了很多。尤其是2.5以来采用的Annotation的参数绑定,极大的方便了开发,3.0对其进行更进一步的完善。对于一些特殊的前台框架,传到后台的不是普通的request中的参数,而是request流中的xml格式,这时就不能采用SpringMVC自带的参数绑定方法。这时候考虑是否能扩展一下。
SpringMVC默认使用的是AnnotationMethodHandlerAdapter.java,可以修改这个类来实现扩展。关键位置在如下方法中:
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是内部类,继承自HandlerMethodInvoker.java,invokeHandlerMethod方法需要扩展,继续跟踪这个方法,发现是HandlerMethodInvoker.java这个类的方法,这个方法中的关键方法是resolveHandlerArguments(),关键部分如下
if (RequestParam.class.isInstance(paramAnn)) {
RequestParam requestParam = (RequestParam) paramAnn;
paramName = requestParam.value();
required = requestParam.required();
defaultValue = parseDefaultValueAttribute(requestParam.defaultValue());
annotationsFound++;
}
else if (RequestHeader.class.isInstance(paramAnn)) {
RequestHeader requestHeader = (RequestHeader) paramAnn;
headerName = requestHeader.value();
required = requestHeader.required();
defaultValue = parseDefaultValueAttribute(requestHeader.defaultValue());
annotationsFound++;
}
到此扩展的话需要添加自己的类型,如RequestParamExt,添加在后面,模仿如下:
else if (RequestParamExt.class.isInstance(paramAnn)) {
RequestParamExtrequestParam = (RequestParamExt) paramAnn;
paramName = requestParam.value();
defaultValue = parseDefaultValueAttribute(requestParam.defaultValue());
miType = requestParam.type();
annotationsFound++;
}
在
else if (paramName != null) {
args[i] = resolveRequestParam(paramName, required, defaultValue, methodParam, webRequest, handler);
}
这个方法上面添加扩展逻辑:
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);
}
}
两个resolveRequest*Ext方法如下:
protected Object resolveRequestStrParamExt(PlatformRequest platformRequest, MethodParameter methodParam){
VariableList inVl = platformRequest.getVariableList();
String para