方法对象Spring MVC SimpleFormController

本文纯属个人见解,是对前面学习的总结,如有描述不正确的地方还请高手指正~

    

赠人玫瑰,手留余香.人生最大的乐快不在于有占什么而在于求追什么的进程.

参考文章:http://fhd001.iteye.com/blog/1131713  http://blog.sina.com.cn/s/blog_4b8677cd0100089t.html 

http://www.cnblogs.com/hibernate3-example/archive/2011/10/26/2492534.html

    

    

SimpleFormController是AbstractFormController的详细现实,许允你在置配文件里通过successView和formView属性来置配功成图视(表单功成提交后要转向的页面)和表单图视(示显表单的页面);如果提交不法合(有三种可能:1.validator犯错。2.bind错误,也就是说从请求中取提参数封装到command的进程当中现出了型类转化错误,比如将一个含字母字符串转换为Integer。3.onBindAndValidate()方法犯错),则会新重返回到表单图视;如果提交法合,onSubmit()方法的认默现实会转向功成页面,当然你可以覆写该方法在转向之前充填一些你想返回的信息。

    

 

    

    SimpleFormController的任务流与AbstractFormController差不多,独一的不同是你不必自己去现实showForm()和processFormSubmission()。showForm()这个方法经已被类SimpleFormController现实了并被限定为final,你不可以在承继SimpleFormController的子类里覆写这个类。processFormSubmission()这个方法尽管可以去覆写但由于它几乎可以满意全部的要求,因此一般也不会有人去写重它。

    


它的处置流程是这样的:
get请求来到时,这样处置:
1) 请求传递给一个controller对象
2) 用调formBackingObject()方法,创立一个command对象的实例。
3) 用调initBinder(),册注要需的型类转换器
4) 用调showForm()方法,返回备准呈现给户用的图视 ,如果“bindOnNewForm”属性设为true,则ServletRequestDataBinder会将初始请求参数填入一个新的表单对象,并且执行onBindOnNewForm()方法。
5) 用调referenceData()方法,备准给户用示显关相的数据。如户用登录要需选择的年度信息
6) 返回formView指定的图视

对应的活动图如下:

    方法和对象

    

post请求来到时,这样处置:
1) 如果sessionForm属性没有设定,则用调formBackingObject()方法,创立一个command对象的实例。否则从session中得取表单对象
2) 将请求传来的参数入写command对象,看它的源代码,会发明它是这样来做的:

    

ServletRequestDataBinder binder = createBinder(request, command);
binder.bind(request);

    

3)执行onBind()方法,在绑定数据以后,验证数据之前对表单数据停止一些自制的改修作动。 
4) 如果设置为要求验证(validateOnBinding属性被设定),则用调validator类停止数据验证
5) 用调onBindAndValidate()方法,该方法许允自定义数据绑定和验校处置
6)执行processFormSubmission()验检 Errors对象中含不含错误,如果含有错误则执行showForm()返回到填写表单页面;否则执行onSubmit()方法,停止提交表单,然后转向功成页面。
响应的活动图如下:

    方法和对象

    即:1.当表单控制器接收到GET请求时,它用调formBackingObject()方法,创立表单对象。该方法可以被子类覆盖,对于编辑操纵的表单说来,你可以通过该方法从数据库中加载表单对象,当表单页面示显时,表单示显出待编辑的数据了;

2.表单对象和页面表单数据之间要需通过属性编辑器现实向双转化,对于非基本数据型类或String型类的属性说来,你可能要需册注一些自定义编辑器。你可以通过覆盖initBinder()方法,通过用调binder.registerCustomEditor()的方法册注编辑器; 

3.表单对象通过bindOnNewForm属性(可以通过置配设置,认默为false)判断是不是要需将GET请求参数绑定到formBackingObject()方法创立的表单对象中。如果bindOnNewForm为true,执行绑定操纵,在绑定成完后,还将用调onBindOnNewForm()回调方法(子类可以供提详细现实)。否则到下一步。不过一般情况下,GET请求参数是于用加载等编辑表单对象的ID值,如topicId、forumId等,一般无需停止绑定; 

4.用调referenceData()方法(子类可供提详细现实)备准一些关联的数据,如性别下拉框数据,学历下拉框数据等。一般采取ModelMap创立图视务业中要需用到的请求属性数据,键为属性名,值为属性值,如ModelMap("param1", "paramValue1");

5.应用控制器formView定义的图视染渲表单对象; 

6.户用填写或变动表单后,提交表单,向表单控制器起发一个POST请求; 

7.接收到POST请求时,表单控制器晓得这是一个表单数据提交的操纵,所以启动表单提交处置流程; 

8.首先通过sessionForm属性判断表单控制器是不是启用了Session。如果启用了Session,直接从Session中掏出原表单对象,否则再次用调formBackingObject()方法构造出一个表单对象。sessionForm认默为false,可以通过置配停止整调,启用Session可能高提运行能性,但会占用定一的内存; 

9.将POST请求参数充填到表单对象中; 

10.用调onBind()方法,该方法许允你在表单充填成完后,法合性验校之前执行一些特定的操纵; 

11.如果validateOnBinding属性设置为true,册注在控制器中的验校器开始任务,对表单对象的属性值执行法合性验校。如果有法合性错误,将被册注到Errors对象中(关于如何册注验校器,我们将稍后分析);

12.用调onBindAndValidate()方法,该方法许允你在数据绑定及法合性验校后,执行一些额定的自定义操纵,你也可以在这里,执行一些额定的法合性验校; 

13.用调processFormSubmission()方法处置提交任务,该方法部内又包括后续几步任务;

14.判断方法入参传入errors是不是包括错误,如果包括错误返回到formView对应的表单页面中,否则到下一步; 

15.通过isFormChangeRequest()方法(认默为false)判断请求是不是为表单变动请求,如果为true,用调onFormChange()方法,然后返回到formView对应的表单页面,否则到下一步; 

16.如果子类覆盖了onSubmit()方法,执行之,否则执行子类的doSubmitAction()方法。通过这两者之一成完务业的处置,然后返回successView属性指定的功成页面。

    每日一道理
无知者为梦想中的虚幻而苦苦等待,换回的不是所求的,而是岁月在脸上留下的印痕,一事无成的人一生便是虚度。生活中,与其花时间去等待,不如加快步伐去追寻理想,试着与时间赛跑,也许身躯、心理会感到劳累,但这样的生活毕竟是充实的。

    

    

    在web应用程序中,经常要处置表单。表单控制器既要为户用示显表单,又要处置表单提交。表单处置多是件非常复杂且满充变数的任务。如果从头开始构建表单控制器,会牵涉到太多的表单处置细节。

    Spring MVC供提的SimpleFormController类定义了基本的表单处置流程。它支撑令命对象的观点,并且可以将表单域的值绑定到令命对象的同名属性上。通过扩展SimpleFormController类,控制器以可就承继处置表单的能力。

    当HTTP GET请求SimpleFormController示显表单时, 它会将表单图视呈现给户用。当HTTP POST请求提交该表单时,SimpleFormController就会将表单域的值绑定到令命对象上,并用调onSubmit()方法,以这类式方来处置表单提交。如果表单处置功成,会呈现success图视。否则,呈现带错误信息的表单图视。

    为了应适不同的表单需求,SimpleFormController许允你覆盖其中的生命周期方法,以此定制表单处置流程。

     

    创立表单控制器

    通过扩展SimpleFormController类,可为以这个控制器指定令命类(在本例中是Reservation),然后表单域的值将被绑定到令命对象的同名属性中。你还可以指定图视要问访的令命对象的名称(在本例中是reservation),但这是可选的,认默名称为command。

package com.sunshine.controller;

import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.validation.BindException;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;

import com.sunshine.pojo.UserModel;

public class RegisterController extends SimpleFormController {

	/**
	 * 可以通过依赖注入 注入令命现实类 ,也可以在类的构造方法中应用父类的方法 setCommandClass(Class) public
	 * LoginCommandController(){ setCommandClass(UserModel.class); }
	 */

	@Override
	protected Object formBackingObject(HttpServletRequest request)
			throws Exception {
		UserModel user = new UserModel();
		user.setName("请输入户用名");
		return user;
	}

	@Override
	protected Map<String, Object> referenceData(HttpServletRequest request)
			throws Exception {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("cityList", Arrays.asList("山东", "北京", "上海"));
		return map;
	}

	/*
	 * @Override protected void doSubmitAction(Object command) throws Exception
	 * { UserModel userModel = (UserModel) command;
	 * System.out.println(userModel); }
	 */

	@Override
	protected ModelAndView onSubmit(Object command, BindException errors)
			throws Exception {
		System.out.println("RegisterController.onSubmit()");
		UserModel userModel = (UserModel) command;

		ModelAndView modelAndView = new ModelAndView();

		modelAndView.setViewName(getSuccessView());
		modelAndView.addObject("user", userModel);

		return modelAndView;
	}

	protected void initBinder(HttpServletRequest request,
			ServletRequestDataBinder binder) throws Exception {
		System.out.println("RegisterController.initBinder()");
		binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
//		binder.registerCustomEditor(Date.class,"birthday", new DateEditor());
	}

	/*@Override
	protected void onBind(HttpServletRequest request, Object command)
			throws Exception {
		// TODO Auto-generated method stub
		super.onBind(request, command);
		System.out.println("RegisterController.onBind()");
	}*/

}

    由于表单域的值都是作为字符串提交的,为了将这些绑定到令命对象上,表单控制器可能要需停止型类转换。型类转换现实是由册注在这个控制器中的属性编辑器来执行的。Spring先预册注了几个属性编辑器,用来转换大家熟知的数据型类,如数字型类尔布型类。你必须为其他的数据型类册注定制的编辑器,,如java.util.Date。定制的属性编辑器都被册注到initBinder()方法ServletRequestDataBinder参数中。在绑定表单域值时如果产生任何错误,SimpleFormController会动自呈现带有错误信息的表单图视。如果一切顺利,则会用调onSubmit()方法来处置表单提交。在onSubmit()方法中,可以通过参数获得绑定了表单域值的令命对象。对于这个控制器而言,它是个Reservation对象,因为你将令命类设置为Reservation。onSubmit()方法的三个变体可供覆盖。为了问访符合你要需的方法参数,该应覆盖它们中最简略的那个。 

protected ModelAndView onSubmit(Object command)throws Exception;
protected ModelAndView onSubmit(Object command,BindException errors)
	throws Exception;
protected ModelAndView onSubmit(HttpServletRequest request,HttpServletResponse response,
	Object command,BindException errors)throws Exception;

    在覆盖onSubmit()方法时,必须返回ModelAndView对象。如果只要在令命对象上执行一个作动,并在这个作动成完时返回功成图视,可以覆盖doSubmitAction()方法,它的返回型类为void,认默呈现功成图视。

    在声明这个控制器时,为了停止预订,还要需一个指向服务层中的reservationService Bean的用引。此外,还必须为这个表单控制器设置表单图视和功成图视,分别是formView和successView属性。

<bean id="registerController" class="com.sunshine.controller.RegisterController">
		<!-- 可以通过依赖注入 注入令命现实类 ,也可以在类的构造方法中应用父类的方法setCommandClass(Class)--> 
		<property name="commandClass" value="com.sunshine.pojo.UserModel"/>
		<property name="commandName" value="user"></property>
		<property name="formView" value="register"></property>
		<property name="successView" value="success"></property>
	</bean>

文章结束给大家分享下程序员的一些笑话语录: 关于编程语言
如果 C++是一把锤子的话,那么编程就会变成大手指头。
如果你找了一百万只猴子来敲打一百万个键盘,那么会有一只猴子会敲出一 段 Java 程序,而其余的只会敲出 Perl 程序。
一阵急促的敲门声,“谁啊!”,过了 5 分钟,门外传来“Java”。
如果说 Java 很不错是因为它可以运行在所有的操作系统上,那么就可以说 肛交很不错,因为其可以使用于所有的性别上。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值