SimpleFormController 工作流程

SimpleFormController 工作流程
2008-12-05 15:42

由于SimpleFormController是继承AbstractFormController,在该AbstractFormController中的handleRequestInternal方法需要判断当前提交的方法是Get还是Post,如果是Get则是New一个View,如果是Post则是运行客户端业务逻辑,然后跳转到成功页面。
  • 通过Get 方式请求一个View

1、Controller受到一个Get请求;

2、formBackingObject()方法,如果需要读取数据库,这里是一个比较好的地方去做这件事情。然后将Object通过request.setAttribute来传递到页面;如果页面表单需要绑定多个Object,可以在这里读取数据库取得,然后设置到页面上。

3、initBinder() 这里是用来进行数据格式化转换的;如果在页面上显示某些类型需要进行格式化显示,那么需要在XXXXFormController中重载该方法,指定特定的转换器完成对特定Object的设置。如对于日期格式需要在本方法中增加如下代码:

binder.registerCustomEditor(Date.class, null, new CustomDateEditor(

new SimpleDateFormat("MM/dd/yyyy"),true));

4、调用AbstractFormController.handleRequestInternal方法,在该方法中判断,如果是新建一个Form View,则调用ShowNewForm方法,在ShowNewForm方法中调用了ShowForm方法,SimpleFormController实现了此方法,指向的url是Controller中注册的formView参数。

6、View 模块完成,显示给用户。

  • 通过Post方式提交一个Form

1、 提交后根据Action指向的URL在urlMapping配置中找到指定的Controller;

2、 如果配置了Validator则使用该Validator(见applicationContext-validation.xml)进行相关的验证;缺省是beanValidator。错误信息写入到errors参数里。

3、 调用AbstractFormController.handleRequestInternal方法,在该方法中判断是通过Post来调用此方法,则调用processFormSubmission方法,该方法会先判断errors中是否有验证错误,如果有则返回到原表单页面,显示错误信息。

4、 验证通过后进入onSubmit方法,该方法的command参数对应绑定到页面的对象,

如果在表单中有多个对象需要进行绑定,那么其它对象可以通过this.bindAndValidate(HttpServletRequest request, Object command);方法来进行绑定。

5、 做相关的业务操作。

6、 往返回界面上输出结果提示信息,通过getText和saveMessage()方法完成。getText()第一个参数是在资源文件中的信息代码,第二个参数是发给该信息的参数,在该信息中通过{0}来读取,第三个参数是当前使用的Locale。saveMessage()的信息显示是通过common\messages.jsp来进行。

7、 返回一个ModelAndView(new RedirectView(success)),success对应action-servlet.xml文件该Controller所配置successView,跳转路径是相对路径。

而对于MultiActionController来说,要么继承这个类,要么给它设个delegate,注意不能类中出现方法多态。相对简单一些

SimpleFormController流程 引用

SimpleFormController往上繼承自AbstractFormController,而又繼承自AbstractController,
這是開始實作Controller介面的基底類別,再往上的兩個類別各司WebApplicationContext與Http response的資源。

  對於簡單的表單需求,我們通常透過繼承SimpleFormController,並覆寫其onSumit()方法來完成表單功能,
而實際上真正的表單處理流程定義在AbstractFormController

  這邊說明三個我覺得比較常用且不複雜的方法,在繼承了SimpleFormController(AbstractFormController)之後,
您可以覆寫這些方法:formBackingObject()、referenceData()、onBindAndValidate()。

  當瀏覽器使用GET方法向Action發出請求時,會調用formBackingObject()方法,您可以在這個方法中預先設定好表單物件,在表單網頁中就會顯示表單的預設值,例如:

java 代码
  1. protected Object formBackingObject(HttpServletRequest request) throws Exception {   
  2.      LoginForm loginForm = new LoginForm();   
  3.      loginForm.setUsername("guest");   
  4.      loginForm.setPassword("guest");   
  5.   
  6.     return loginForm;   
  7. }  

在使用者送出資料之後,如果sessionForm為false,則會再呼叫formBackingObject()方法取得表單物件,若sessionForm設定為true,則會試著有session中找尋表單物件。

您可以在referenceData()中定義一些JSP頁面可以參考到的參數,例如:

java 代码
  1. protected Map referenceData(HttpServletRequest request) throws Exception {   
  2.      Map ref = new HashMap();   
  3.      ref.put("defalutUser", "guest");   
  4.   
  5.     return ref;   
  6. }  

onBindAndValidate()就如其名所示,當表單物件的資料已經綁定,並且還沒開始驗證之前,您可以試著在這個方法中作一些預處理,例如進行字母大小寫轉換,附帶一些額外的資訊等等:

java 代码
  1. protected void onBindAndValidate(HttpServletRequest request, Object command, BindException errors) throws Exception {   
  2. }  

url请求来到时,这样处理:
    a) 请求传递给一个controller对象
    b) 调用formBackingObject()方法,创建一个command对象的实例。
    c) 调用initBinder(),注册需要的类型转换器
    d) 调用showForm()方法,返回准备呈现给用户的视图
    e) 调用referenceData()方法,准备给用户显示相关的数据。如用户登录需要选择的年度信息
    f) 返回formView指定的视图
表单请求来到时,这样处理:
    a) 调用formBackingObject()方法,创建一个command对象的实例。
    b) 将请求传来的参数写入command对象
    c) 如果设置为要求验证,则调用validator类进行数据验证
    d) 调用onBindAndValidate()方法,该方法允许自定义数据绑定和校验处理
    e) 调用onSubmit()方法,进行业务逻辑处理

SimpleFormController本身的强大和复杂性从上图就可以看出。实际上,SimpleController除了在处理上要经过一个多步的流程,而且在处理不同类型请求时(如post,get)。(希望大家看一下上面的图和bean定义)

下面是SimpleFormController的处理流程,分为post方法和get方法。
get方法处理流程(一般连接的形式为get方法):
  1. 按请求转到相应controller;
  2. 调用formBackingObject()方法,创建一个command对象的实例(如果设定了commandClass,则不需要override formBackingObject()方法了);
  3. 调用initBinder(),注册需要的类型转换器;
  4. 调用showForm()方法,返回一个view,即准备呈现给用户的视图,一般情况下这个方法是不需要override的,只需设定formView即可;
  5. 调用referenceData()方法。这个方法返回一个Map对象,可以把在view中需要展现的数据放入这个Map中;
  6. 转到formView指定的视图。

一般情况下步骤2,3,4的方法是不需要override的,它们只需要在配置文件中进行相关属性的定义即可。而步骤5的referenceData()一般是要在自己的SimpleFormController中进行重新定义的。

post方法处理流程(一般用于处理表单):

  1. 按请求转到相应controller;
  2. 调用formBackingObject()方法,创建一个command对象的实例(如果设定了commandClass,则不需要override formBackingObject()方法了);
  3. 把请求参数注入表单对象;
  4. 执行onBind()方法;
  5. 执行validator验证。
  6. 执行onBindAndValidate()方法;
  7. 若有err,则转到formView视图;
  8. 执行onSubmit()方法或doSubmitAction()方法。
同处理get方法一样,步骤2的formBackingObject()方法一般是不会去重载的。步骤3也不需要我们做什么。真正需要我们做的是4,5,6,8步。当然4,5,6是可选的,如果有需要,可以去实现它们中的一个或几个,执行的步骤是按上面的顺序。但步骤8的两个方法是必须选一个的(两个都override是没有意义的)。
这里要说明一下onSubmit()方法和doSubmitAction()方法。在SimpleFormController中,有三种形式的onSubmit方法,它们是:
  • onSubmit(req, res, command, errs);
  • onSubmit(command, errs);
  • onSubmit(command);

但是这三种方法不是孤立的,第一个方法在执行中会调用第二个方法,第二个方法在执行中会调用第三个方法。一般在定义自己的SimpleFormController时只是override onSubmit(command)方法。

doSubmitAction()方法是一个有意思的方法,它的完整定义如下:

protected void doSubmitAction(Object obj) throws Exception

它的返回类型是void,而不是我们预想的ModelAndView,并且也不返回任何视图层需要的数据。实际上doSubmitAction执行完毕后会自动转到successView视图。并且如果配合sessionForm来使用的的话(sessionForm设为true),那么在转到successView视图后,在session中可以取到先前的表单对象(所谓的POJO)。

说了这么多,还是看个实例比较形象(SimpleFormController(中))。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值