Spring MVC使用AbstractWizardFormController处理多页表单

在上一个Spring MVC表单处理示例中 ,我们应该使用SimpleFormController来处理单页表单提交,这非常简单明了。

但是,有时您可能需要处理“ 向导表单 ”,该向导表单需要将表单处理成多个页面,并要求用户逐页填写表单。 在此向导表单情况下,主要关注的是如何存储模型数据(用户填写的数据)并将其带到多个页面中?

SAbstractWizardFormController

幸运的是,Spring MVC附带了AbstractWizardFormController类,可以轻松处理此向导表单。 在本教程中,我们向您展示如何使用AbstractWizardFormController类在多个页面上存储和带来表单数据,应用验证并在最后一页显示表单数据。

1.向导表单页面

本演示共5页,按以下顺序工作:

[User] --> WelcomePage --> Page1 --> Page2 --> Page3 --> ResultPage

使用AbstractWizardFormController ,页面顺序由提交按钮的“名称”确定:

  1. _finish:完成向导表单。
  2. _cancel:取消向导窗体。
  3. _targetx:移至目标页面,其中x是从零开始的页面索引。 例如_target0_target1等。

1. WelcomePage.jsp
欢迎页面,带有用于启动向导表单过程的超链接。

<html>
<body>
	<h2>Handling multipage forms in Spring MVC</h2>
	Click here to start playing -
	<a href="user.htm">AbstractWizardFormController example</a>
</body>
</html>

2. Page1Form.jsp
第1页,带有“用户名”文本框,显示错误消息(如果有),并包含2个提交按钮,其中:

  1. _target1 –移至第2页。
  2. _cancel –取消向导表单过程并将其移至“取消”页面
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
<head>
<style>
.error {
	color: #ff0000;
}

.errorblock {
	color: #000;
	background-color: #ffEEEE;
	border: 3px solid #ff0000;
	padding: 8px;
	margin: 16px;
}
</style>
</head>

<body>
	<h2>Page1Form.jsp</h2>

	<form:form method="POST" commandName="userForm">
		<form:errors path="*" cssClass="errorblock" element="div" />
		<table>
			<tr>
				<td>Username :</td>
				<td><form:input path="userName" />
				</td>
				<td><form:errors path="userName" cssClass="error" />
				</td>
			</tr>
			<tr>
			<tr>
				<td colspan="3"><input type="submit" value="Next"
					name="_target1" /> <input type="submit" value="Cancel"
					name="_cancel" /></td>
			</tr>
		</table>
	</form:form>

</body>
</html>

3. Page2Form.jsp
第2页,带有“密码”字段,显示错误消息(如果有),并包含3个提交按钮,其中:

  1. _target0 –移至第1页。
  2. _target2 –移至第3页。
  3. _cancel –取消向导表单过程并将其移至“取消”页面
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
<head>
<style>
.error {
	color: #ff0000;
}

.errorblock {
	color: #000;
	background-color: #ffEEEE;
	border: 3px solid #ff0000;
	padding: 8px;
	margin: 16px;
}
</style>
</head>

<body>
	<h2>Page2Form.jsp</h2>

	<form:form method="POST" commandName="userForm">
		<form:errors path="*" cssClass="errorblock" element="div" />
		<table>
			<tr>
				<td>Password :</td>
				<td><form:password path="password" />
				</td>
				<td><form:errors path="password" cssClass="error" />
				</td>
			</tr>
			<tr>
			<tr>
				<td colspan="3"><input type="submit" value="Previous"
					name="_target0" /> <input type="submit" value="Next"
					name="_target2" /> <input type="submit" value="Cancel"
					name="_cancel" /></td>
			</tr>
		</table>
	</form:form>

</body>
</html>

4. Page3Form.jsp
第3页,带有“备注”文本框,显示错误消息(如果有),并包含3个提交按钮,其中:

  1. _target1 –移至第2页。
  2. _finish –完成向导表单处理并将其移至完成页面。
  3. _cancel –取消向导表单过程并将其移至“取消”页面。
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
<head>
<style>
.error {
	color: #ff0000;
}

.errorblock {
	color: #000;
	background-color: #ffEEEE;
	border: 3px solid #ff0000;
	padding: 8px;
	margin: 16px;
}
</style>
</head>

<body>
	<h2>Page3Form.jsp</h2>

	<form:form method="POST" commandName="userForm">
		<form:errors path="*" cssClass="errorblock" element="div" />
		<table>
			<tr>
				<td>Remark :</td>
				<td><form:input path="remark" />
				</td>
				<td><form:errors path="remark" cssClass="error" />
				</td>
			</tr>
			<tr>
			<tr>
				<td colspan="3"><input type="submit" value="Previous"
					name="_target1" /> <input type="submit" value="Finish"
					name="_finish" /> <input type="submit" value="Cancel"
					name="_cancel" /></td>
			</tr>
		</table>
	</form:form>

</body>
</html>

5. ResultForm.jsp
显示从前3页收集的所有表单数据。

<html>
<body>
	<h2>ResultForm.jsp</h2>

	<table>
		<tr>
			<td>UserName :</td>
			<td>${user.userName}</td>
		</tr>
		<tr>
			<td>Password :</td>
			<td>${user.password}</td>
		</tr>
		<tr>
			<td>Remark :</td>
			<td>${user.remark}</td>
		</tr>
	</table>

</body>
</html>

2.型号

创建一个模型类来存储表单的数据。

文件:User.java

package com.mkyong.common.model;

public class User{
	
	String userName;
	String password;
	String remark;
	
	//getter and setter methods
}

3. AbstractWizardFormController

扩展AbstractWizardFormController ,只需重写以下方法

  1. processFinish –用户单击“ _finish ”名称的提交按钮时触发
  2. processCancel –用户单击名称为“ _cancel ”的提交按钮时触发
  3. formBackingObject –使用“用户”模型类将所有表单数据存储在多个页面中。

文件:UserController.java

package com.mkyong.common.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.validation.BindException;
import org.springframework.validation.Errors;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractWizardFormController;
import com.mkyong.common.model.User;
import com.mkyong.common.validator.UserValidator;

public class UserController extends AbstractWizardFormController{

	public UserController(){
		setCommandName("userForm");
	}
	
	@Override
	protected Object formBackingObject(HttpServletRequest request)
		throws Exception {
		
		return new User();
	}
	@Override
	protected ModelAndView processFinish(HttpServletRequest request,
		HttpServletResponse response, Object command, BindException errors)
		throws Exception {
		
		//Get the data from command object
		User user = (User)command;
		System.out.println(user);
		
		//where is the finish page?
		return new ModelAndView("ResultForm", "user", user);
	}

	@Override
	protected ModelAndView processCancel(HttpServletRequest request,
		HttpServletResponse response, Object command, BindException errors)
		throws Exception {
		
		//where is the cancel page?
		return new ModelAndView("WelcomePage");
	}
}

一个简单的控制器,用于返回“ WelcomePage ”视图。

文件:WelcomeController.java

package com.mkyong.common.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

public class WelcomeController extends AbstractController{

	@Override
	protected ModelAndView handleRequestInternal(HttpServletRequest request,
		HttpServletResponse response) throws Exception {
		
		return new ModelAndView("WelcomePage");
	}

}

4.多页/向导表单验证

SimpleFormController ,创建一个验证器类,将所有验证逻辑放入validate()方法内,然后将验证器装饰性地注册到简单表单控制器。

但是,它在AbstractWizardFormController中有点不同。 首先,创建一个验证器类,以及每个页面的验证方法,如下所示:

档案:UserValidator.java

package com.mkyong.common.validator;

import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
import com.mkyong.common.model.User;

public class UserValidator implements Validator{

	@Override
	public boolean supports(Class clazz) {
		//just validate the User instances
		return User.class.isAssignableFrom(clazz);
	}
	
	//validate page 1, userName
	public void validatePage1Form(Object target, Errors errors) {
		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "userName",
		        "required.userName", "Field name is required.");
	}
	
	//validate page 2, password
	public void validatePage2Form(Object target, Errors errors) {
		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "password",
			"required.password", "Field name is required.");
	}
	
	//validate page 3, remark
	public void validatePage3Form(Object target, Errors errors) {
		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "remark",
			"required.remark", "Field name is required.");
	}
	
	@Override
	public void validate(Object target, Errors errors) {
		validatePage1Form(target, errors);
		validatePage2Form(target, errors);
		validatePage3Form(target, errors);
	}
}

File:User.properties –用于存储错误消息的属性

required.userName = Username is required!
required.password = Password is required!
required.remark = Remark is required!

并且,在向导表单控制器( UserController.java )中,通过手动调用验证器来覆盖validatePage() (不再像简单表单控制器那样声明)。

请参阅UserController.java的更新版本。

public class UserController extends AbstractWizardFormController{
	//other methods, see above

	@Override
	protected void validatePage(Object command, Errors errors, int page) {
		
		UserValidator validator = (UserValidator) getValidator();
		
		//page is 0-indexed
		switch (page) {
		   case 0: //if page 1 , go validate with validatePage1Form
			validator.validatePage1Form(command, errors);
			break;
		   case 1: //if page 2 , go validate with validatePage2Form
			validator.validatePage2Form(command, errors);
			break;
		   case 2: //if page 3 , go validate with validatePage3Form
			validator.validatePage3Form(command, errors);
			break;
		}
	}
}

validatePage()方法中,使用“ switch ”函数确定正在调用的页面并将其与相应的验证器关联。 该页面的索引为0。

5.弹簧配置

声明向导表单控制器( UserController.java ),以正确的顺序放置所有页面并注册一个验证器。

<bean class="com.mkyong.common.controller.UserController" >
    	   <property name="pages">
		<list>
		<!-- follow sequence -->
		<value>Page1Form</value> <!-- page1, _target0 -->
		<value>Page2Form</value> <!-- page2, _target1 -->
		<value>Page3Form</value> <!-- page3, _target2 -->
		</list>
	   </property>
	   <property name="validator">
		<bean class="com.mkyong.common.validator.UserValidator" />
	   </property>
       </bean>

注意
在“页面”属性中,列表值的顺序用于定义向导表单中页面的顺序。

查看完整示例:

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

 <bean 
  class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping" />
    
    <bean class="com.mkyong.common.controller.WelcomeController" />  
    <bean class="com.mkyong.common.controller.UserController" >
    	<property name="pages">
	   <list>
		<!-- follow sequence -->
		<value>Page1Form</value> <!-- page1 -->
		<value>Page2Form</value> <!-- page2 -->
		<value>Page3Form</value> <!-- page3 -->
	   </list>
	   </property>
	   <property name="validator">
		<bean class="com.mkyong.common.validator.UserValidator" />
	   </property>
      </bean>
 
      <!-- Register User.properties for validation error message -->
      <bean id="messageSource"
           class="org.springframework.context.support.ResourceBundleMessageSource">
	   <property name="basename" value="User" />
      </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>

5.演示

网址: http:// localhost:8080 / SpringMVC / welcome.htm

1. WelcomePage.jsp ,单击链接,移至Page1Form.jsp

SpringMVC-Multipage-Forms-Example1

2. Page1Form.jsp ,包含一个“用户名”文本框字段和两个按钮:

  1. “下一个”按钮–移至Page2Form.jsp。
  2. “取消”按钮–移至WelcomePage.jsp
SpringMVC-Multipage-Forms-Example2

如果在提交表单时“用户名”为空,则显示错误消息。

SpringMVC-Multipage-Forms-Example2-Error

3. Page2Form.jsp ,包含一个“ password”字段和3个按钮:

  1. “上一个”按钮–移至Page1Form.jsp。
  2. “下一个”按钮–移至Page3Form.jsp。
  3. “取消”按钮–移至WelcomePage.jsp。
SpringMVC-Multipage-Forms-Example3

4. Page3Form.jsp ,包含一个“备注”文本框字段和3个按钮:

  1. “上一个”按钮–移至Page2Form.jsp。
  2. “完成”按钮–移至ResultForm.jsp。
  3. “取消”按钮–移至WelcomePage.jsp。
SpringMVC-Multipage-Forms-Example4

5. ResultForm.jsp ,显示所有表单数据。

SpringMVC-Multipage-Forms-Example5

下载源代码

下载它– SpringMVC-MultiPage-Form-Handling-Example.zip (12KB)

参考文献

  1. AbstractWizardFormController Javadoc
  2. Spring MVC表单处理示例

翻译自: https://mkyong.com/spring-mvc/spring-mvc-handling-multipage-forms-with-abstractwizardformcontroller/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值