首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

[SpringMVC]修改源码使之能够愈加智能的自动装配request请求参数

2013-11-08 
[SpringMVC]修改源码使之能够更加智能的自动装配request请求参数转自:http://s929498110.iteye.com/blog/1

[SpringMVC]修改源码使之能够更加智能的自动装配request请求参数

转自:http://s929498110.iteye.com/blog/1558098

[SpringMVC]修改源码使之能够更加智能的自动装配request请求参数.博客分类:?
  • 技术杂谈
  • 项目构架企业应用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请求参数
    1. <form>??
    2. ????......<!--省去代码若干-->??
    3. ????<input?type='text'?name='mark'/>?<!--?原料的mark?-->??
    4. ????......<!--省去代码若干-->??
    5. ????<input?type='text'?name='mark'/>?<!--?辅料的mark?-->??
    6. ????......<!--省去代码若干-->??
    7. </form>??

    ?这种情况下,我感觉使用SpringMVC很麻烦,或许是自己知识短浅,找不到解决办法。

    ?

    但是我也想到了为什么SpringMVC不能像Struts2一样,可以再name标签上添加一个obj.?呢?如果可以添加obj.?的话,这种情况根本没有一点复杂的:

    Java代码??[SpringMVC]修改源码使之能够愈加智能的自动装配request请求参数
    1. <form>??
    2. ????......<!--省去代码若干-->??
    3. ????<input?type='y.text'?name='mark'/>?<!--?原料的mark,action中原料参数名为y?-->??
    4. ????......<!--省去代码若干-->??
    5. ????<input?type='f.text'?name='mark'/>?<!--?辅料的mark,action中辅料参数名为f?-->??
    6. ????......<!--省去代码若干-->??
    7. </form>??

    ?

    可惜, SpringMVC没有这个功能,因此,我便动了修改它源码的念头。经过一番折腾,终于完成了,现将修改方法公布出来,供大家参考:

    ?

    需要修改的Spring类全部都在org.springframework.web.jar包中,我使用的是3.0.6版本。

    ?

    ?

    第一步,修改org.springframework.web.bind.annotation.support.HandlerMethodInvoker类的

    private WebDataBinder resolveModelAttribute(...)方法?:

    Java代码??[SpringMVC]修改源码使之能够愈加智能的自动装配request请求参数
    1. private?WebDataBinder?resolveModelAttribute(String?attrName,??
    2. ????????MethodParameter?methodParam,?ExtendedModelMap?implicitModel,??
    3. ????????NativeWebRequest?webRequest,?Object?handler)?throws?Exception?{??
    4. ????????//?.......省去若干行??
    5. ????//?原Spring中为name,应将name改为methodParam.getParameterName()??
    6. ????WebDataBinder?binder?=?createBinder(webRequest,?bindObject,?methodParam.getParameterName());??
    7. ????initBinder(handler,?name,?binder,?webRequest);??
    8. ????return?binder;??
    9. }??

    ?

    第二步,修改org.springframework.web.bind.ServletRequestParameterPropertyValues类,最后新增两个方法?:

    Java代码??[SpringMVC]修改源码使之能够愈加智能的自动装配request请求参数
    1. /**?
    2. ?*?新增的构造方法,此方法添加了一个ServletRequestDataBinder类型参数,用于获取方法arg名称?
    3. ?*?@param?request?
    4. ?*?@param?binder?
    5. ?*/??
    6. public?ServletRequestParameterPropertyValues(ServletRequest?request,?ServletRequestDataBinder?binder){??
    7. ????//?super(WebUtils.getParametersStartingWith(request,?(prefix?!=?null???prefix?+?prefixSeparator?:?null)));??
    8. ????super(getAvailableParams(request,?binder));??
    9. }??
    10. ??
    11. /**?
    12. ?*?新增方法,此方法内部将target.property提取为property?
    13. ?*?@param?request?
    14. ?*?@param?binder?
    15. ?*?@return?
    16. ?*/??
    17. public?static?Map<String,?Object>?getAvailableParams(ServletRequest?request,?ServletRequestDataBinder?binder){??
    18. ????//?此方法内部优先提取target.property值,之后再取property值??
    19. ????Map<String,?Object>?params?=?new?HashMap<String,?Object>();??
    20. ????Enumeration<String>?paramNames?=?request.getParameterNames();??
    21. ????while?(paramNames?!=?null?&&?paramNames.hasMoreElements())?{??
    22. ????????String?paramName?=?(String)?paramNames.nextElement();?//?parameter名称??
    23. ????????String[]?values?=?request.getParameterValues(paramName);??
    24. ????????//?如果是以target.开始的参数则去除target.??
    25. ????????if(paramName.startsWith(binder.getObjectName()+".")){??
    26. ????????????paramName?=?paramName.substring(paramName.indexOf('.')+1);??
    27. ????????}else{??
    28. ????????????if(params.containsKey(paramName))??
    29. ????????????????continue;??
    30. ????????}??
    31. ????????if?(values?==?null?||?values.length?==?0)?{??
    32. ????????????//?Do?nothing,?no?values?found?at?all.??
    33. ????????}?else?if?(values.length?>?1)?{??
    34. ????????????params.put(paramName,?values);??
    35. ????????}?else?{??
    36. ????????????params.put(paramName,?values[0]);??
    37. ????????}??
    38. ????}??
    39. ????return?params;??
    40. }??

    ?

    第三步,修改org.springframework.web.bind.ServletRequestDataBinder类的

    public void bind(ServletRequest request)方法?:

    Java代码??[SpringMVC]修改源码使之能够愈加智能的自动装配request请求参数
    1. public?void?bind(ServletRequest?request)?{??
    2. ????????//?此处原来为new?ServletRequestParameterPropertyValues(request)??
    3. ????MutablePropertyValues?mpvs?=?new?ServletRequestParameterPropertyValues(request,?this);??
    4. ????MultipartRequest?multipartRequest?=?WebUtils.getNativeRequest(request,?MultipartRequest.class);??
    5. ????if?(multipartRequest?!=?null)?{??
    6. ????????bindMultipart(multipartRequest.getMultiFileMap(),?mpvs);??
    7. ????}??
    8. ????doBind(mpvs);??
    9. }??

    ?

    大功告成,此时,你便可以将form表单中的同名不同类参数修改为obj.property?,以标明同名的参数分别归哪个对象[SpringMVC]修改源码使之能够愈加智能的自动装配request请求参数

    ?

    现将修改之后的org.springframework.web-3.0.6.jar发布出来,如果你使用的是不同版本的Spring,可以采取上面的步骤自己重新打包使用[SpringMVC]修改源码使之能够愈加智能的自动装配request请求参数

    ?

    ?

    谢谢观看,完毕~~~~~