`
s929498110
  • 浏览: 106590 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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

阅读更多

记得以前用Struts2时候,有种说法好像叫做自动装配(可能名字记错了,见谅),就是将request中的<form>表单自动组装为java对象。然而后来使用SpringMVC之后,发现SpringMVC这一点做得有些差强人意。因为Struts2能够自动组装的是<input name="obj.property"> 这种request参数名,而SpringMVC自动组装的是<input name="property"> 这种参数名,虽然仅仅少了个obj. ,但是用起来差别很大。

 

比如在管理系统中,有时候一个form表单中会涉及多个类。我最近遇到的一个form表单中有两种类,一个是辅料 ,一种是原料 。两种原料中都有一些同名的参数mark 。在form表单中是这样的:

<form>
    ......<!--省去代码若干-->
    <input type='text' name='mark'/> <!-- 原料的mark -->
    ......<!--省去代码若干-->
    <input type='text' name='mark'/> <!-- 辅料的mark -->
    ......<!--省去代码若干-->
</form>

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

 

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

<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(...)方法

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类,最后新增两个方法

/**
 * 新增的构造方法,此方法添加了一个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)方法

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 ,以标明同名的参数分别归哪个对象

 

现将修改之后的org.springframework.web-3.0.6.jar发布出来,如果你使用的是不同版本的Spring,可以采取上面的步骤自己重新打包使用

 

 

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

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    springmvc注解详解

    `@RequestBody` 注解用于将请求体的内容映射到方法参数上,通常用于接收 JSON 或 XML 数据。Spring MVC 自动将请求体的内容转换为指定的对象类型。 ### 7. `@ResponseBody` `@ResponseBody` 注解用于将方法返回的...

    springMVC 注解版

    在 Spring MVC 中,注解大大简化了传统 XML 配置,使代码更加简洁和易于维护。 **1. Spring MVC 注解概述** 在 Spring MVC 中,常用的注解包括: - `@Controller`:标记一个类为 Spring MVC 的控制器,处理来自...

    SpringMVC精品资源--教程源码-springboot部分SpringMVC常用的注解; SpringBoot.zip

    SpringMVC是Spring框架的一部分,专门用于处理Web应用程序的请求-响应模型。它是一个轻量级的、基于注解的控制器模型,简化了Java Web开发。在Spring Boot中,SpringMVC被集成并进一步优化,使得创建独立运行的、...

    springmvc 学习指南 源码 app06-app12

    6. **模型数据绑定**:Spring MVC 支持自动将请求参数绑定到控制器方法的参数上,反之亦然。这在处理表单提交和 JSON 数据时非常有用。通过 `@RequestParam`、`@PathVariable` 和 `@RequestBody` 等注解,你可以看到...

    马士兵Spring源码剖析文档

    Spring与Mybatis的整合使开发者能够方便地进行数据库操作,同时利用Spring的事务管理功能。通过SqlSessionFactory和SqlSession,Mybatis动态地生成SQL,执行并返回结果。 通过阅读《马士兵Spring源码剖析文档》,...

    SSM集成应用

    配置SpringMVC,使其能够调用service层提供的服务,并将结果返回给客户端。 **4.7 SSM实例** 一个完整的SSM框架整合示例项目,涵盖从数据库连接到页面展示的整个流程。 #### Spring框架详解 **5.1 Spring的特点*...

    毕业设计基于SSM框架和微信小程序开发的民宿酒店管理系统源码.zip

    - 小程序与后端系统交互通常通过API接口,利用微信小程序的网络请求API,如wx.request(),向服务器发送数据并接收响应。 3. **民宿酒店管理系统**: - 这样的系统通常包括房间管理、预订管理、入住退房管理、用户...

    spring mvc + spring + mybatis+json整合

    在Spring MVC中,Controller和其他服务类可以通过@Autowired注解自动装配,实现依赖注入。同时,Spring还提供了AOP(Aspect-Oriented Programming,面向切面编程)功能,可以用于日志记录、权限验证等跨切面关注点。...

    Java面试可能问的问题.docx

    - `@RequestBody`:将请求体内容转化为方法参数。 - `@ResponseBody`:将方法的返回值直接写入HTTP响应体。 - `@RequestParam`:从请求参数中获取值。 - `@PathVariable`:从URL模板变量中获取值。 - `@...

    ssm的注解框架

    在SpringMVC中,`@RequestMapping`用于映射HTTP请求到处理方法,`@PathVariable`、`@RequestParam`、`@RequestHeader`等用于获取请求参数。`@Controller`注解标识控制器类,`@ResponseBody`将方法返回值直接写入HTTP...

    [SSM完整项目]仿豆瓣优秀电影评分系统_rezip.zip

    1. **Spring框架**:Spring是Java领域的一个核心框架,它提供了依赖注入(DI)和面向切面编程(AOP)等功能,使得代码更加模块化,易于管理和测试。在本项目中,Spring管理了应用的bean,如DAO、Service等,通过XML...

    [SSM完整项目]仿豆瓣优秀电影评分系统_rezip1.zip

    1. **Spring框架**:Spring是Java领域的一个核心框架,它提供了依赖注入(DI)和面向切面编程(AOP)等功能,使得代码更加模块化,易于管理和测试。在本项目中,Spring管理了应用的bean,如DAO、Service等,通过XML...

    [SSM完整项目]仿豆瓣优秀电影评分系统

    1. **Spring框架**:Spring是Java领域的一个核心框架,它提供了依赖注入(DI)和面向切面编程(AOP)等功能,使得代码更加模块化,易于管理和测试。在本项目中,Spring管理了应用的bean,如DAO、Service等,通过XML...

Global site tag (gtag.js) - Google Analytics