Spring 表单处理

1. SimpleFormController vs @Controller

In XML-based Spring MVC web application, you create a form controller by extending the SimpleFormController class.

In annotation-based, you can use @Controller instead.

SimpleFormController

public class CustomerController extends SimpleFormController{
      //...
}

Annotation

@Controller
@RequestMapping("/customer.htm")
public class CustomerController{
      //...
}

 

2. formBackingObject() vs RequestMethod.GET

In SimpleFormController, you can initialize the command object for binding in the formBackingObject() method. In annotation-based, you can do the same by annotated the method name with @RequestMapping(method = RequestMethod.GET).

SimpleFormController

        @Override
	protected Object formBackingObject(HttpServletRequest request)
		throws Exception {
 
		Customer cust = new Customer();
		//Make "Spring MVC" as default checked value
		cust.setFavFramework(new String []{"Spring MVC"});
 
		return cust;
	}

Annotation

        @RequestMapping(method = RequestMethod.GET)
	public String initForm(ModelMap model){
 
		Customer cust = new Customer();
		//Make "Spring MVC" as default checked value
		cust.setFavFramework(new String []{"Spring MVC"});
 
		//command object
		model.addAttribute("customer", cust);
 
		//return form view
		return "CustomerForm";
	}

3. onSubmit() vs RequestMethod.POST

In SimpleFormController, the form submission is handle by the onSubmit() method. In annotation-based, you can do the same by annotated the method name with @RequestMapping(method = RequestMethod.POST).

SimpleFormController

       @Override
	protected ModelAndView onSubmit(HttpServletRequest request,
		HttpServletResponse response, Object command, BindException errors)
		throws Exception {
 
		Customer customer = (Customer)command;
		return new ModelAndView("CustomerSuccess");
 
	}

Annotation

	@RequestMapping(method = RequestMethod.POST)
	public String processSubmit(
		@ModelAttribute("customer") Customer customer,
		BindingResult result, SessionStatus status) {
 
		//clear the command object from the session
		status.setComplete();
 
		//return form success view
		return "CustomerSuccess";
 
	}

4. referenceData() vs @ModelAttribute

In SimpleFormController, usually you put the reference data in model via referenceData() method, so that the form view can access it. In annotation-based, you can do the same by annotated the method name with @ModelAttribute.

SimpleFormController

	@Override
	protected Map referenceData(HttpServletRequest request) throws Exception {
 
		Map referenceData = new HashMap();
 
		//Data referencing for web framework checkboxes
		List<String> webFrameworkList = new ArrayList<String>();
		webFrameworkList.add("Spring MVC");
		webFrameworkList.add("Struts 1");
		webFrameworkList.add("Struts 2");
		webFrameworkList.add("JSF");
		webFrameworkList.add("Apache Wicket");
		referenceData.put("webFrameworkList", webFrameworkList);
 
		return referenceData;
	}

Spring’s form

	<form:checkboxes items="${webFrameworkList}" path="favFramework" />

Annotation

	@ModelAttribute("webFrameworkList")
	public List<String> populateWebFrameworkList() {
 
		//Data referencing for web framework checkboxes
		List<String> webFrameworkList = new ArrayList<String>();
		webFrameworkList.add("Spring MVC");
		webFrameworkList.add("Struts 1");
		webFrameworkList.add("Struts 2");
		webFrameworkList.add("JSF");
		webFrameworkList.add("Apache Wicket");
 
		return webFrameworkList;
	}

Spring’s form

	<form:checkboxes items="${webFrameworkList}" path="favFramework" />

5. initBinder() vs @InitBinder

In SimpleFormController, you define the binding or register the custom property editor via initBinder() method. In annotation-based, you can do the same by annotated the method name with @InitBinder.

SimpleFormController

    protected void initBinder(HttpServletRequest request,
		ServletRequestDataBinder binder) throws Exception {
 
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
    }

Annotation

	@InitBinder
	public void initBinder(WebDataBinder binder) {
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
 
		binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
	}

From Validation

In SimpleFormController, you have to register and map the validator class to the controller class via XML bean configuration file, and the validation checking and work flows will be executed automatically.

In annotation-based, you have to explicitly execute the validator and define the validation flow in the @Controller class manually. See the different :

SimpleFormController

	<bean class="com.mkyong.customer.controller.CustomerController">
                <property name="formView" value="CustomerForm" />
		<property name="successView" value="CustomerSuccess" />
 
		<!-- Map a validator -->
		<property name="validator">
			<bean class="com.mkyong.customer.validator.CustomerValidator" />
		</property>
	</bean>

Annotation

@Controller
@RequestMapping("/customer.htm")
public class CustomerController{
 
	CustomerValidator customerValidator;
 
	@Autowired
	public CustomerController(CustomerValidator customerValidator){
		this.customerValidator = customerValidator;
	}
 
	@RequestMapping(method = RequestMethod.POST)
	public String processSubmit(
		@ModelAttribute("customer") Customer customer,
		BindingResult result, SessionStatus status) {
 
		customerValidator.validate(customer, result);
 
		if (result.hasErrors()) {
			//if validator failed
			return "CustomerForm";
		} else {
			status.setComplete();
			//form success
			return "CustomerSuccess";
		}
	}
	//...

Full Example

See a complete @Controller example.

package com.mkyong.customer.controller;
 
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.support.SessionStatus;
 
import com.mkyong.customer.model.Customer;
import com.mkyong.customer.validator.CustomerValidator;
 
@Controller
@RequestMapping("/customer.htm")
public class CustomerController{
 
	CustomerValidator customerValidator;
 
	@Autowired
	public CustomerController(CustomerValidator customerValidator){
		this.customerValidator = customerValidator;
	}
 
	@RequestMapping(method = RequestMethod.POST)
	public String processSubmit(
		@ModelAttribute("customer") Customer customer,
		BindingResult result, SessionStatus status) {
 
		customerValidator.validate(customer, result);
 
		if (result.hasErrors()) {
			//if validator failed
			return "CustomerForm";
		} else {
			status.setComplete();
			//form success
			return "CustomerSuccess";
		}
	}
 
	@RequestMapping(method = RequestMethod.GET)
	public String initForm(ModelMap model){
 
		Customer cust = new Customer();
		//Make "Spring MVC" as default checked value
		cust.setFavFramework(new String []{"Spring MVC"});
 
		//Make "Make" as default radio button selected value
		cust.setSex("M");
 
		//make "Hibernate" as the default java skills selection
		cust.setJavaSkills("Hibernate");
 
		//initilize a hidden value
		cust.setSecretValue("I'm hidden value");
 
		//command object
		model.addAttribute("customer", cust);
 
		//return form view
		return "CustomerForm";
	}
 
 
	@ModelAttribute("webFrameworkList")
	public List<String> populateWebFrameworkList() {
 
		//Data referencing for web framework checkboxes
		List<String> webFrameworkList = new ArrayList<String>();
		webFrameworkList.add("Spring MVC");
		webFrameworkList.add("Struts 1");
		webFrameworkList.add("Struts 2");
		webFrameworkList.add("JSF");
		webFrameworkList.add("Apache Wicket");
 
		return webFrameworkList;
	}
 
	@InitBinder
	public void initBinder(WebDataBinder binder) {
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
 
		binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
 
	}
 
	@ModelAttribute("numberList")
	public List<String> populateNumberList() {
 
		//Data referencing for number radiobuttons
		List<String> numberList = new ArrayList<String>();
		numberList.add("Number 1");
		numberList.add("Number 2");
		numberList.add("Number 3");
		numberList.add("Number 4");
		numberList.add("Number 5");
 
		return numberList;
	}
 
	@ModelAttribute("javaSkillsList")
	public Map<String,String> populateJavaSkillList() {
 
		//Data referencing for java skills list box
		Map<String,String> javaSkill = new LinkedHashMap<String,String>();
		javaSkill.put("Hibernate", "Hibernate");
		javaSkill.put("Spring", "Spring");
		javaSkill.put("Apache Wicket", "Apache Wicket");
		javaSkill.put("Struts", "Struts");
 
		return javaSkill;
	}
 
	@ModelAttribute("countryList")
	public Map<String,String> populateCountryList() {
 
		//Data referencing for java skills list box
		Map<String,String> country = new LinkedHashMap<String,String>();
		country.put("US", "United Stated");
		country.put("CHINA", "China");
		country.put("SG", "Singapore");
		country.put("MY", "Malaysia");
 
		return country;
	}
}

To make annotation work, you have to enable the component auto scanning feature in Spring.

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context-2.5.xsd">
 
	<context:component-scan base-package="com.mkyong.customer.controller" />
 
	<bean class="com.mkyong.customer.validator.CustomerValidator" />
 
 	<!-- Register the Customer.properties -->
	<bean id="messageSource"
		class="org.springframework.context.support.ResourceBundleMessageSource">
		<property name="basename" value="com/mkyong/customer/properties/Customer" />
	</bean>
 
	<bean id="viewResolver"
	      class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
              <property name="prefix">
                 <value>/WEB-INF/pages/</value>
              </property>
              <property name="suffix">
                 <value>.jsp</value>
              </property>
        </bean>
</beans>

Download Source Code

Download it – SpringMVC-Form-Handling-Annotation-Example.zip (12KB)

时间: 2024-10-17 09:00:26

Spring 表单处理的相关文章

Spring表单参数绑定中对“is”开头的boolean类型字段的的处理

之前在新浪微博上面发了一个微薄: 弱弱的发现在定义boolean类型的时候最好不要使用"is"开头,可以避免一些问题哦   然后有一些朋友朋友问我为什么,当时比较忙,现在写篇文章举一个例子,回复一下这个问题. 最近在使用Spring MVC的时候vo定义了一个字段,一开始字段名字为:isAddCertificateInfo, 相应的get和set方法如下: public boolean isAddCertificateInfo() { return isAddCertificateIn

使用Spring MVC表单标签

概述 在低版本的Spring中,你必须通过JSTL或<spring:bind>将表单对象绑定到HTML表单页面中,对于习惯了Struts表单标签的开发者来说,Spring MVC的这一表现确实让人失望.不过这一情况已经一去不复返了,从Spring 2.0开始,Spring MVC开始全面支持表单标签,通过Spring MVC表单标签,我们可以很容易地将控制器相关的表单对象绑定到HTML表单元素中. 在上一篇文章<Spring MVC的表单控制器>中(http://tech.it16

表单-新手spring,controller没有被调用问题

问题描述 新手spring,controller没有被调用问题 在index.jsp上登录-->login.jsp页面. login.jsp上有两个静态的连接add.jsp和sel.jsp 然后点add.jsp 是一个添加用户的表单 输入数据提交后 没有任何显示 debug报: 2015-11-20 11:06:56,613 [http-bio-9090-exec-10] DEBUG [org.springframework.web.servlet.mvc.method.annotation.R

用Spring MVC来处理向导式复杂表单

引子 我们在网上经常会碰到一些向导式的表单页面,比如 第一步 >> 第二步 >> 第三步-.基本信息 >> 联系方式 >> 兴趣爱好-.它们都是按类型分到多个有序的页面要你来完成填写的.当然,你也可以把它们全部罗列在一个页面里,那样用户就会感觉茫茫然,分不清主次,可能不会很好的予以配合. 然而像 Struts.WebWork 那样的 MVC 框架未提供类似的实现,都需自己采用某种方式来实现向导,可以用层的隐现方式,或逐步把填写的部分数据放 Session 中

spring json-spring mvc 表单提交问题 请教

问题描述 spring mvc 表单提交问题 请教 请先参考附图.. 请教问题如下: 1.保存时,标识1 的基本信息 和 标识2 的订单明细信息一块提交保存么? 2.如果上述的标识1 和 标识2 的信息一块保存,怎么保存? 个人经历: spring 的controller 如果是如下的一般(非接收json)方式,如下: @RequestMapping(value = "create", method = RequestMethod.POST) @ResponseBody public

ajax spring-ajax方式提交表单,spring mvc的Controller中怎么不能返回视图

问题描述 ajax方式提交表单,spring mvc的Controller中怎么不能返回视图 ajax请求到springmvc的Controller后,请求成功后为什么不跳转到jsp?就是这句:return new ModelAndView(""/sys/selectAccount"");不用ajax请求就可以 解决方案 使用ajax提交的请求 控制器中的重定向 或者请求转发都是无效的 ajax要跳转页面 只能把你要跳转的页面发送到前端 前端ajax的回调函数使用前

spring封装表单标签用意

问题描述 spring封装表单标签用意 现在在用springmvc ,看了表单标签库, spring 为什么要封装表单标签? 解决方案 便于代码的重用. 解决方案二: 为了更好的支持国际化和在后台使用注解对表单字段的验证

技术-spring 3+hibernate 4+JSP 表单上传文件

问题描述 spring 3+hibernate 4+JSP 表单上传文件 我使用spring 3+hibernate 4+JSP表单来上传文件,application.XML文件如果配置oracleLobHandler启动时就会报Bean property 'lobHandler' is not writable or has an invalid setter method错误,如果不配置的话在保存时会保org.springframework.orm.hibernate3.support.Bl

spring mvc 接收表单 bean

spring MVC如何接收表单bean 呢? 之前项目中MVC框架一直用struts2,所以我也就按照struts2 的思维来思考 页面loginInput.jsp: Html代码   <?xml version="1.0" encoding="UTF-8" ?>   <%@ page language="java" contentType="text/html; charset=UTF-8"