`

Spring MVC form data binding and ajax form

阅读更多
Model和View绑定是虽然不是MVC模式的标配,但是Model和View的绑定,为开发者提供的非常方便的方式:视图的数据自动和模型同步并装配完成,避免了繁琐的手工装配过程。
Spring MVC提供了复杂的绑定机制和验证机制(前面的一个文章介绍了更复杂的动态列表的绑定)
我们先看看绑定机制:
我们以广告订单为例,在请求创建订单表单的action中,我们添加一个新创建的模型advertiseOrder:
@RequestMapping("/getCreateForm")
public ModelAndView getCreateForm(){
	ModelAndView mav = new ModelAndView();
        //add the model which the 
	mav.addObject("advertiseOrder", new AdvertiseOrder());
        //other data the form need
	List<User> sales = userManager.getUsersByType(User.SALE_TYPE);
	mav.addObject("saleList",sales);
	List<User> customerAids = userManager.getUsersByType(User.CUSTOMER_AID);
	mav.addObject("customerAidList",customerAids);

	mav.setViewName("advertiseOrders/create_order");
	return mav;
}


在表单的页面_order_form.jsp,我们使用spring的form标签,指定commandName为我们在控制器中的名字advertiseOrder,
然后表单的每个数据域的path和模型的字段对应。另外使用form:select的option自动会被选中为value和模型对应字段的值相同的。
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

<form:form commandName="advertiseOrder" id="orderForm" action="${param.actionURL}" method="post">
	<div class="form">
		<table cellpadding="0" cellspacing="0" >
			<tr>
				<th>广告主</th>
				<td>
					<form:hidden class="textbox" path="customerId"/>
					<input class="textbox" id="customerName" type="text" value="${advertiserName}"/>
					<span class="po">广告主名称</span>
					<form:errors class="error" path="customerId"/>
				</td>
			</tr>
			<tr>
				<th><form:label for="name" path="name">订单名称</form:label></th>
				<td>
					<form:hidden path="id"/>
					<form:input class="textbox" path="name"/>
					<span class="po">包含广告主名称,计费类型,业务类型等</span>
					<form:errors class="error" path="name"/>
				</td>
			</tr>
			<tr>
				<th><form:label for="startTime" path="startTime">订单时间</form:label></th>
				<td>
					<div class="qcbox">
							<div class="labelContainer"></div>
							<div class="boxWrapper">
								<div class="boxContainer">
									<div class="sinfo" title=""></div>
									<div class="sicon" id="fromTimeIcon"></div>
									<div style="clear: both;"></div>
								</div>
							</div>
							<form:input path="startTime" class="textbox0"/>
					 </div>
					 <div class="ln">-</div>
					 <div class="qcbox">
						<div class="labelContainer"></div>
						<div class="boxWrapper">
							<div class="boxContainer">
								<div class="sinfo" title=""></div>
								<div class="sicon" id="toTimeIcon"></div>
								<div style="clear: both;"></div>
							</div>
						</div>
						<form:input path="endTime" class="textbox0"/>
					</div>
					<form:errors class="error" path="startTime"/>&nbsp;&nbsp;
					<form:errors class="error" path="endTime"/>
				</td>
			</tr>
			<tr>
				<th><form:label path="description">订单说明</form:label>
				<td>
					<form:textarea class="textbox" path="description"></form:textarea>
				</td>
			</tr>
			<tr>
				<th><form:label path="saleId">销售人员</form:label></th>
				<td><div class="fg">
						<div class="list">
							<form:select class="name" path="saleId" onchange="onSelectOrderSale()">
								<option value="">选择销售人员</option>
								<form:options items="${saleList}" itemValue="id" itemLabel="usrName"></form:options>
							</form:select>
							<form:hidden path="sale"/>
						</div>
						<form:errors class="error" path="saleId"/>
					</div>
				</td>
			</tr>
			<tr>
				<th><form:label path="customerAidId">客服人员</form:label></th>
				<td><div class="list">
						<form:select class="name" path="customerAidId" onchange="onSelectOrderCustomerAid()">
						 	<option value="">选择客服人员</option>
							<form:options items="${customerAidList}" itemValue="id" itemLabel="usrName"/>
						</form:select>
						<form:hidden path="customerAid"/>
					</div>
					<form:errors class="error" path="customerAidId"/>
				</td>
			</tr>
			<tr>
				<th></th>
				<td><input class="button"  type="submit" value="保 存" /></td>
			</tr>
		</table>
	</div>
</form:form>

表单提交到创建订单的action:我们使用ModelAttribute的注解绑定表单的对象和@Valid注解需要验证的模型(注:BindingResult参数必须在@ModelAttribute注解参数的下一个):
@RequestMapping("/create")
public ModelAndView create(@ModelAttribute("advertiseOrder") @Valid AdvertiseOrder order,
						 BindingResult result,HttpSession session){
	ModelAndView mav = new ModelAndView();
	if(result.hasErrors()){
		mav.setViewName("advertiseOrders/create_order");
		List<User> sales = userManager.getUsersByType(User.SALE_TYPE);
		mav.addObject("saleList",sales);
		List<User> customerAids = userManager.getUsersByType(User.CUSTOMER_AID);
		mav.addObject("customerAidList",customerAids);
		mav.addObject("errors", result);
		mav.addObject("advertiseOrder", order);
	}else{
		User user = (User) session.getAttribute("user");
		order.setOperator(user.getUsrName());
		advertiseOrderManager.create(order);
		mav.setViewName("redirect:list");
	}
	return mav;
}

如果字段的类型需要转换(spring自定默认提供多了很多类型转换,比如String和Integer,Float,Date之间的转换),我们也可以自定义类型转换,比如Timestamp类型,我们需要指定的格式字符串和Timestamp类型的转化的Editor。在执行业务逻辑之前,我们还需要对模型的数据进行验证,也就是表单后台验证,我们只需要在控制器中的使用@InitBinder中注册自定义的类型转换器和添加指定模型验证即可:
@InitBinder
public void initBinder(WebDataBinder binder, WebRequest request) {
	if(binder.getTarget() instanceof AdvertiseOrder){
		binder.setValidator(new AdvertiseOrderValidator());
                //自定义字段类型转换的customerEditor
		binder.registerCustomEditor(java.sql.Timestamp.class, new TimestampEditor("yyyy-MM-dd", true)); 
	}
}

然后写我们验证器代码:
package com.qunar.advertisement.advertiser.vo;

import java.sql.Timestamp;

import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;

import com.qunar.advertisement.advertiser.model.AdvertiseOrder;

public class AdvertiseOrderValidator implements Validator {

	@Override
	public boolean supports(Class<?> clazz) {
		return clazz == AdvertiseOrder.class;
	}

	@Override
	public void validate(Object target, Errors errors) {
		ValidationUtils.rejectIfEmpty(errors, "customerId", "field.required",new Object[]{"广告主"});
		ValidationUtils.rejectIfEmpty(errors, "name", "field.required",new Object[]{"订单名称"});
		ValidationUtils.rejectIfEmpty(errors, "startTime", "field.required",new Object[]{"订单开始时间"});
		ValidationUtils.rejectIfEmpty(errors, "endTime", "field.required",new Object[]{"订单结束时间"});
		ValidationUtils.rejectIfEmpty(errors, "saleId", "field.required",new Object[]{"销售人员"});
		ValidationUtils.rejectIfEmpty(errors, "customerAidId", "field.required",new Object[]{"客服人员"});
		
		if(errors.hasErrors())
			return;
		AdvertiseOrder order = (AdvertiseOrder)target;
		Timestamp startTime = order.getStartTime();
		Timestamp endTime = order.getEndTime();
		if(endTime.before(startTime)){
			errors.rejectValue("endTime", "endTime_must_after_startTime");
		}
	}
}

我们在messages_zh.properties配置要显示的错误信息:
引用

field.required=({0})不能为空
endTime_must_after_startTime=结束时间必须晚于开始时间

还需要在配置messageSource指定错误信息配置文件路径、cache时间和编码:
 <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
	<property name="basename" value="/WEB-INF/messages/messages" />
	<property name="cacheSeconds" value="0" />
	<property name="defaultEncoding" value="UTF-8"/>
</bean>

在页面中使用<form:errors class="error" path="xxx"/>显示错误提示:
这样一个包含后端验证的Model和View绑定的全部逻辑已经完成。但是新的问题又来了,我们需要的是支持ajax的form,因为我们的系统基本上所有的页面都是ajax局部刷新的,
而一个普通的表单提交会直接转向到结果页面。而我们需要的是返回的页面直接嵌入到我们指定的标签下。
幸好jquery有一个plugin,叫做jquery form plugin,提供了能够满足我们需求的ajax form
写了一个简单的方法,可以直接将我们表单变成ajax的方式提交:
function ajax_form(formId){
	$('#' + formId).ajaxForm({
		target: '#main'//结果目标页面插入的id为#main的element下
	});
}

我们在下面的代码放在_order_form.jsp的最后:
<script language="javascript">
	ajax_form('orderForm');
</script>

这样当_order_form.jsp片段被加载时,会执行ajax_form的初始化的代码。
分享到:
评论

相关推荐

    Spring MVC 学习笔记 十一 data binding

    **Spring MVC 数据绑定详解** 在Web开发中,Spring MVC框架为我们提供了一种高效的数据绑定机制,使得控制器(Controller)能够方便地将用户提交的表单数据与Java对象进行映射,简化了处理HTTP请求和响应的过程。本...

    最全最经典spring-mvc教程

    另外,Spring MVC与Spring框架的其他组件无缝集成,如Spring AOP(面向切面编程)用于实现日志、事务管理等功能,Spring JDBC和MyBatis等持久层框架用于数据库操作,以及Spring Data JPA、Hibernate等ORM工具,使得...

    Spring web MVC和spring 2.0 form tag解说

    **Spring Web MVC与Spring 2.0 Form Tag详解** 在Web开发领域,Spring Web MVC作为一款强大的MVC框架,被广泛应用于构建企业级的Web应用。它提供了模型(model)、视图(view)和控制器(controller)的分离,使得开发者...

    spring MVC .docx

    10. **Conversion and Validation**: Spring MVC提供了数据转换和验证功能,如使用`@RequestParam`、`@PathVariable`注解自动转换参数,以及使用`@Valid`和`BindingResult`进行表单验证。 11. **Tiles or Layouts**...

    Spring mvc5.0.3 所有jar包

    **Spring MVC 5.0.3 知识点详解** Spring MVC是Spring框架的一个核心模块,专注于构建Web应用程序。在Spring MVC 5.0.3版本中,它提供了丰富的功能和改进,使得开发者能够更高效地开发RESTful服务、处理HTTP请求、...

    spring mvc demo

    - **数据绑定与验证(Data Binding and Validation)**:使用`@Valid`注解进行数据验证,并显示错误信息。 - **异常处理(Exception Handling)**:自定义全局异常处理器,统一处理应用程序可能出现的异常。 - **...

    Spring MVC资料

    19. **Ajax集成**:Spring MVC支持与jQuery、AngularJS等JavaScript库进行Ajax交互。 20. **测试**:Spring MVC提供了MockMVC,可以在没有Web服务器的情况下进行单元测试和集成测试。 以上知识点涵盖了Spring MVC...

    Spring MVC 实例

    **Spring MVC 框架详解** Spring MVC 是 Spring 框架的重要组成部分,它是一个用于构建 Web 应用程序的模型-视图-控制器(MVC)架构。Spring MVC 提供了灵活的处理机制,包括处理器映射、视图解析、数据绑定、本地...

    spring MVC配置,六步简单搞定

    Spring MVC 是一个基于Java的轻量级Web应用框架,它为构建模型-视图-控制器(MVC)架构的应用程序提供了强大的支持。这篇博客“spring MVC配置,六步简单搞定”可能介绍了如何快速且有效地设置Spring MVC项目。下面...

    Spring MVC A Tutorial Second Edition

    Spring MVC是目前流行的基于Java的企业级Web应用开发框架之一,是Spring框架的一个子项目。它遵循MVC(Model-View-Controller,模型-视图-控制器)设计模式,广泛应用于图形用户界面(GUI)的开发中,不仅限于Web...

    spring mvc项目后端源码

    10. **验证**:Spring MVC 结合 `Hibernate Validator` 提供了表单验证功能,可以使用 `@Valid` 和 `BindingResult` 进行校验。 11. **RESTful 风格**:通过 `@RestController` 注解和 HTTP 方法注解(`@GetMapping...

    《精通Spring MVC 4 Geoffroy Warin》 PDF

    12. **Data Binding and Validation**:Spring MVC支持数据绑定,将HTTP请求参数自动映射到模型对象,同时提供验证机制确保数据质量。 13. **Multipart Support**:处理文件上传,Spring MVC内置了对multipart请求...

    Spring Mvc(1)Spring MVC 校验

    public String register(@Validated({RegistrationChecks.class, PasswordChecks.class}) RegistrationForm form, BindingResult result) { // 处理结果并保存用户 } ``` 上述示例中,`RegistrationChecks` 和...

    基于Spring MVC的web应用

    9. **验证**:Spring MVC 提供了 Data Binding 和 Validation 功能,可以方便地对用户输入进行验证。 10. **异常处理**:通过统一的 ExceptionHandler 或 @ExceptionHandler 注解,可以集中处理全局或特定类型的...

    Spring MVC 配套资料

    Spring MVC 是一个基于 Java 的轻量级 Web 开发框架,它是 Spring 框架的重要组成部分,主要用于构建 MVC(Model-View-Controller)架构的 web 应用程序。本配套资料包含 SpringMvc 学习笔记与代码示例,是学习 ...

    Ajax-JQuery-JSON-Form-Binding.zip

    Ajax-JQuery-JSON-Form-Binding.zip,用于将json数据绑定到表单的轻量级插件。对于使用ajax和具有大量字段的表单很有用。,ajax代表异步javascript和xml。它是多种web技术的集合,包括html、css、json、xml和...

    Spring mvc小程序

    7. **Validation**:Spring MVC提供验证机制,通过`@Valid`和`BindingResult`可以对模型对象进行校验。 8. **ExceptionHandler**:通过定义`@ExceptionHandler`方法,可以集中处理全局的异常,提高代码的可维护性。...

Global site tag (gtag.js) - Google Analytics