项目构架企业应用SpringSpringMVC?记得以前用Struts2时候,有种说法好像叫做自动装配(可能名字记错了,见谅),就是将request中的<form>表单自动组装为java对象。然而后来使用SpringMVC之后,发现SpringMVC这一点做得有些差强人意。因为Struts2能够自动组装的是<input name="obj.property">?这种request参数名,而SpringMVC自动组装的是<input name="property">?这种参数名,虽然仅仅少了个obj.?,但是用起来差别很大。
?
比如在管理系统中,有时候一个form表单中会涉及多个类。我最近遇到的一个form表单中有两种类,一个是辅料,一种是原料?。两种原料中都有一些同名的参数mark?。在form表单中是这样的:
Java代码??![[SpringMVC]修改源码使之能够愈加智能的自动装配request请求参数](//img.reader8.net/uploadfile/jiaocheng/201401110/2814/2014012818144828979.png)
- <form>??
- ????......<!--省去代码若干-->??
- ????<input?type='text'?name='mark'/>?<!--?原料的mark?-->??
- ????......<!--省去代码若干-->??
- ????<input?type='text'?name='mark'/>?<!--?辅料的mark?-->??
- ????......<!--省去代码若干-->??
- </form>??
?这种情况下,我感觉使用SpringMVC很麻烦,或许是自己知识短浅,找不到解决办法。
?
但是我也想到了为什么SpringMVC不能像Struts2一样,可以再name标签上添加一个obj.?呢?如果可以添加obj.?的话,这种情况根本没有一点复杂的:
Java代码??![[SpringMVC]修改源码使之能够愈加智能的自动装配request请求参数](//img.reader8.net/uploadfile/jiaocheng/201401110/2814/2014012818144828979.png)
- <form>??
- ????......<!--省去代码若干-->??
- ????<input?type='y.text'?name='mark'/>?<!--?原料的mark,action中原料参数名为y?-->??
- ????......<!--省去代码若干-->??
- ????<input?type='f.text'?name='mark'/>?<!--?辅料的mark,action中辅料参数名为f?-->??
- ????......<!--省去代码若干-->??
- </form>??
?
可惜, SpringMVC没有这个功能,因此,我便动了修改它源码的念头。经过一番折腾,终于完成了,现将修改方法公布出来,供大家参考:
?
需要修改的Spring类全部都在org.springframework.web.jar包中,我使用的是3.0.6版本。
?
?
第一步,修改org.springframework.web.bind.annotation.support.HandlerMethodInvoker类的
private WebDataBinder resolveModelAttribute(...)方法?:
Java代码??![[SpringMVC]修改源码使之能够愈加智能的自动装配request请求参数](//img.reader8.net/uploadfile/jiaocheng/201401110/2814/2014012818144828979.png)
- private?WebDataBinder?resolveModelAttribute(String?attrName,??
- ????????MethodParameter?methodParam,?ExtendedModelMap?implicitModel,??
- ????????NativeWebRequest?webRequest,?Object?handler)?throws?Exception?{??
- ????????//?.......省去若干行??
- ????//?原Spring中为name,应将name改为methodParam.getParameterName()??
- ????WebDataBinder?binder?=?createBinder(webRequest,?bindObject,?methodParam.getParameterName());??
- ????initBinder(handler,?name,?binder,?webRequest);??
- ????return?binder;??
- }??
?
第二步,修改org.springframework.web.bind.ServletRequestParameterPropertyValues类,最后新增两个方法?:
Java代码??![[SpringMVC]修改源码使之能够愈加智能的自动装配request请求参数](//img.reader8.net/uploadfile/jiaocheng/201401110/2814/2014012818144828979.png)
- /**?
- ?*?新增的构造方法,此方法添加了一个ServletRequestDataBinder类型参数,用于获取方法arg名称?
- ?*?@param?request?
- ?*?@param?binder?
- ?*/??
- public?ServletRequestParameterPropertyValues(ServletRequest?request,?ServletRequestDataBinder?binder){??
- ????//?super(WebUtils.getParametersStartingWith(request,?(prefix?!=?null???prefix?+?prefixSeparator?:?null)));??
- ????super(getAvailableParams(request,?binder));??
- }??
- ??
- /**?
- ?*?新增方法,此方法内部将target.property提取为property?
- ?*?@param?request?
- ?*?@param?binder?
- ?*?@return?
- ?*/??
- public?static?Map<String,?Object>?getAvailableParams(ServletRequest?request,?ServletRequestDataBinder?binder){??
- ????//?此方法内部优先提取target.property值,之后再取property值??
- ????Map<String,?Object>?params?=?new?HashMap<String,?Object>();??
- ????Enumeration<String>?paramNames?=?request.getParameterNames();??
- ????while?(paramNames?!=?null?&&?paramNames.hasMoreElements())?{??
- ????????String?paramName?=?(String)?paramNames.nextElement();?//?parameter名称??
- ????????String[]?values?=?request.getParameterValues(paramName);??
- ????????//?如果是以target.开始的参数则去除target.??
- ????????if(paramName.startsWith(binder.getObjectName()+".")){??
- ????????????paramName?=?paramName.substring(paramName.indexOf('.')+1);??
- ????????}else{??
- ????????????if(params.containsKey(paramName))??
- ????????????????continue;??
- ????????}??
- ????????if?(values?==?null?||?values.length?==?0)?{??
- ????????????//?Do?nothing,?no?values?found?at?all.??
- ????????}?else?if?(values.length?>?1)?{??
- ????????????params.put(paramName,?values);??
- ????????}?else?{??
- ????????????params.put(paramName,?values[0]);??
- ????????}??
- ????}??
- ????return?params;??
- }??
?
第三步,修改org.springframework.web.bind.ServletRequestDataBinder类的
public void bind(ServletRequest request)方法?:
Java代码??![[SpringMVC]修改源码使之能够愈加智能的自动装配request请求参数](//img.reader8.net/uploadfile/jiaocheng/201401110/2814/2014012818144828979.png)
- public?void?bind(ServletRequest?request)?{??
- ????????//?此处原来为new?ServletRequestParameterPropertyValues(request)??
- ????MutablePropertyValues?mpvs?=?new?ServletRequestParameterPropertyValues(request,?this);??
- ????MultipartRequest?multipartRequest?=?WebUtils.getNativeRequest(request,?MultipartRequest.class);??
- ????if?(multipartRequest?!=?null)?{??
- ????????bindMultipart(multipartRequest.getMultiFileMap(),?mpvs);??
- ????}??
- ????doBind(mpvs);??
- }??
?
大功告成,此时,你便可以将form表单中的同名不同类参数修改为obj.property?,以标明同名的参数分别归哪个对象![[SpringMVC]修改源码使之能够愈加智能的自动装配request请求参数](//img.reader8.net/uploadfile/jiaocheng/201401110/2814/2014012818144828980.gif)
?
现将修改之后的org.springframework.web-3.0.6.jar发布出来,如果你使用的是不同版本的Spring,可以采取上面的步骤自己重新打包使用![[SpringMVC]修改源码使之能够愈加智能的自动装配request请求参数](//img.reader8.net/uploadfile/jiaocheng/201401110/2814/2014012818144828981.gif)
?
?
谢谢观看,完毕~~~~~