`
守望者
  • 浏览: 54329 次
  • 来自: ...
社区版块
存档分类
最新评论

simpleForm流程的思考

阅读更多

最近在研究spring的jpetstore的例子,新建用户的代码有点迷糊

java 代码
  1. package org.springframework.samples.jpetstore.web.spring;   
  2.   
  3. import java.util.HashMap;   
  4. import java.util.Map;   
  5.   
  6. import javax.servlet.http.HttpServletRequest;   
  7. import javax.servlet.http.HttpServletResponse;   
  8.   
  9. import org.springframework.beans.support.PagedListHolder;   
  10. import org.springframework.dao.DataIntegrityViolationException;   
  11. import org.springframework.samples.jpetstore.domain.Account;   
  12. import org.springframework.samples.jpetstore.domain.logic.PetStoreFacade;   
  13. import org.springframework.validation.BindException;   
  14. import org.springframework.validation.ValidationUtils;   
  15. import org.springframework.web.servlet.ModelAndView;   
  16. import org.springframework.web.servlet.mvc.SimpleFormController;   
  17. import org.springframework.web.util.WebUtils;   
  18.   
  19. /**  
  20.  * @author Juergen Hoeller  
  21.  * @since 01.12.2003  
  22.  */  
  23. public class AccountFormController extends SimpleFormController {   
  24.   
  25.     public static final String[] LANGUAGES = {"english""japanese"};   
  26.   
  27.     private PetStoreFacade petStore;   
  28.   
  29.     public AccountFormController() {   
  30. //      经过调试,此构造函数 在显示表单和提交时并没有调用   
  31.        //使form在session范围内有效,针对每一个请求共享同一个Form实例   
  32.         System.out.println("AccountFormController() is called!");   
  33.         setSessionForm(true);   
  34.     //是否绑定了验证   
  35.         setValidateOnBinding(false);   
  36.         //你的commandName是这个accountForm,相当于struts的form   
  37.         setCommandName("accountForm");   
  38.         //set form view 出错时转向的页面   
  39.         setFormView("EditAccountForm");   
  40.     }   
  41.   
  42.     public void setPetStore(PetStoreFacade petStore) {   
  43.         this.petStore = petStore;   
  44.     }   
  45.     //回传数据到表单,最后返回的是Command对象   
  46.     //创建一个command对象的实例,Command对象也就是(POJO),用来封装表单交互传递的数据。   
  47.     //经过调试,在显示表单的时候调用了此方法   
  48.     protected Object formBackingObject(HttpServletRequest request) throws Exception {   
  49.         System.out.println("formBackingObject is called!");   
  50.         UserSession userSession = (UserSession) WebUtils.getSessionAttribute(request, "userSession");   
  51.         if (userSession != null) {   
  52.             //用户已经存在时   
  53.             return new AccountForm(this.petStore.getAccount(userSession.getAccount().getUsername()));   
  54.         }   
  55.         else {   
  56.             //用户不存在,新建一个用户   
  57.             return new AccountForm();   
  58.         }   
  59.     }   
  60. //当你表单的数据已经绑定上,但还没开始验证之前,你可以在这个方法中作一些预处理。    
  61. //自定义数据绑定和校验处理   
  62. //  经过调试,在提交了表单的时候调用了此方法   
  63.     protected void onBindAndValidate(HttpServletRequest request, Object command, BindException errors)   
  64.             throws Exception {   
  65.                   System.out.println("onBindAndValidate is called!");   
  66.         AccountForm accountForm = (AccountForm) command;   
  67.         Account account = accountForm.getAccount();   
  68.   
  69.         if (request.getParameter("account.listOption") == null) {   
  70.             account.setListOption(false);   
  71.         }   
  72.         if (request.getParameter("account.bannerOption") == null) {   
  73.             account.setBannerOption(false);   
  74.         }   
  75.   
  76.         errors.setNestedPath("account");   
  77.         getValidator().validate(account, errors);   
  78.         errors.setNestedPath("");   
  79.   
  80.         if (accountForm.isNewAccount()) {   
  81.             account.setStatus("OK");   
  82.             ValidationUtils.rejectIfEmpty(errors, "account.username""USER_ID_REQUIRED""User ID is required.");   
  83.             if (account.getPassword() == null || account.getPassword().length() < 1 ||   
  84.                     !account.getPassword().equals(accountForm.getRepeatedPassword())) {   
  85.              errors.reject("PASSWORD_MISMATCH",   
  86.                      "Passwords did not match or were not provided. Matching passwords are required.");   
  87.             }   
  88.         }   
  89.         else if (account.getPassword() != null && account.getPassword().length() > 0) {   
  90.           if (!account.getPassword().equals(accountForm.getRepeatedPassword())) {   
  91.                 errors.reject("PASSWORD_MISMATCH",   
  92.                         "Passwords did not match. Matching passwords are required.");   
  93.           }   
  94.       }   
  95.     }   
  96. //referenceData()方法是方便你在JSP页面对一些数据做出调用的   
  97.     //准备给用户显示相关的数据。让用户选择语言信息   
  98. //  经过调试,在显示表单的时候调用了此方法,如果用户存在提交表单也调用了此方法   
  99.     protected Map referenceData(HttpServletRequest request) throws Exception {   
  100.         System.out.println("referenceData is called!");   
  101.         Map model = new HashMap();   
  102.         model.put("languages", LANGUAGES);   
  103.         model.put("categories"this.petStore.getCategoryList());   
  104.         return model;   
  105.     }   
  106. //  经过调试,在提交表单的时候调用了此方法   
  107.     protected ModelAndView onSubmit(   
  108.             HttpServletRequest request, HttpServletResponse response, Object command, BindException errors)   
  109.             throws Exception {   
  110. System.out.println("onSubmit  is called!");   
  111.         AccountForm accountForm = (AccountForm) command;   
  112.         try {   
  113.             if (accountForm.isNewAccount()) {   
  114.                 this.petStore.insertAccount(accountForm.getAccount());   
  115.             }   
  116.             else {   
  117.                 this.petStore.updateAccount(accountForm.getAccount());   
  118.             }   
  119.         }   
  120.         catch (DataIntegrityViolationException ex) {   
  121.             errors.rejectValue("account.username""USER_ID_ALREADY_EXISTS",   
  122.                     "User ID already exists: choose a different ID.");   
  123.             return showForm(request, response, errors);   
  124.         }   
  125.            
  126.         UserSession userSession = new UserSession(this.petStore.getAccount(accountForm.getAccount().getUsername()));   
  127.         PagedListHolder myList = new PagedListHolder(   
  128.                 this.petStore.getProductListByCategory(accountForm.getAccount().getFavouriteCategoryId()));   
  129.         myList.setPageSize(4);   
  130.         userSession.setMyList(myList);   
  131.         request.getSession().setAttribute("userSession", userSession);   
  132.         return super.onSubmit(request, response, command, errors);   
  133.     }   
  134.   
  135. }   

因为simpleForm既显示表单又处理表单,所以我在代码中加入了输出语句来看哪些方法是在显示表单时调用,哪些是在处理表单时调用。答案我是找到了,注释中也标注了,但是还是觉得有点迷糊,referenceData()方法在显示表单时被调用的作用是什么?errors.setNestedPath("account");是 什么意思?感觉好像在这个处理上没有struts的清晰。手头上的 资料对于simpleForm方面的没有这个复杂。文档嘛也似乎看得不是很明白。

java 代码
  1. public AccountFormController() {   
  2. //      经过调试,此构造函数 在显示表单和提交时并没有调用   
  3.        //使form在session范围内有效,针对每一个请求共享同一个Form实例   
  4.         System.out.println("AccountFormController() is called!");   
  5.         setSessionForm(true);   
  6.     //是否绑定了验证   
  7.         setValidateOnBinding(false);   
  8.         //你的commandName是这个accountForm,相当于struts的form   
  9.         setCommandName("accountForm");   
  10.         //set form view 出错时转向的页面   
  11.         setFormView("EditAccountForm");   
  12.     }  

上面这段代码能猜出是什么意思,但 好像没怎么彻底理解。setSessionForm(true);什么时候把表单放到Session中的??

setValidateOnBinding(false);什么时候绑定的验证的呢?setCommandName("accountForm");accountForm是个含有Accout属性和isNewAccount的bean。怎么把表单数据填入accountForm的呢?什么时候填入的呢?

对于流程网上有以下解释:

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

哪位大侠能针对这个代码详细的解释下究竟这个 代码  的处理流程是什么呢?在显示表单时细节是什么?在处理表单时细节是什么?上面代码各个方法是具体意思是什么呢?什么时候调用的?做什么用的呢?

 

  • 描述: simpleForm流程图一
  • 大小: 59.6 KB
  • 描述: simpleForm流程图二
  • 大小: 128.7 KB
分享到:
评论

相关推荐

    Ruby-SimpleForm轻松处理Rails表单

    在Ruby on Rails框架中,构建表单是一项常见的任务,而Simple Form gem就是为了简化这一过程而设计的。Simple Form是一款强大的表单构建器,它提供了一种简洁、直观的方式来创建复杂的表单,使得开发者能更专注于...

    react-simpleform:用于React的简单形式组件

    替罪羊发送电子邮件的简单组件安装npm install react-simpleform --save用法var SimpleMail = require('simplemail')测试npm 测试发布历史1.0.0 初始版本

    Simple Form Fill-crx插件

    语言:English ...您可以在首选项中配置注释 - 它们与在填充之前的项目中匹配但从项目中删除回馈--------您可以在https://github.com/sblask/webextension-simple-forp-flow上报告错误或制作功能请求欢迎补丁。

    简单的表格填充「Simple Form Fill」-crx插件

    您可以在首选项中配置注释-在添加反馈之前,注释会与项目匹配但已从项目中删除--------您可以在https://github.com/sblask/webextension-simple上报告错误或提出功能请求欢迎填写表格。 支持语言:English

    js代码-schema form: simple form

    const SimpleForm = () =&gt; { const formData = {/* 初始数据或从服务器获取 */}; const onSubmit = (data, errors) =&gt; { if (!errors) { // 提交表单逻辑 } }; return ( &lt;Form schema={schema} // 上述...

    simple_form_wysihtml:将 Wysihtml5 编辑器与 Rails 和 Simple Form 集成

    gem 'simple_form_wysihtml' 并执行: $ bundle 或者自己安装: $ gem install simple_form_wysihtml 要使其工作,您需要在application.js要求 javascripts : //= require simple_form_wysihtml 您可以选择...

    Simple Student Form Registration App

    "Simple Student Form Registration App" 是一个使用JavaScript技术构建的应用,主要目标是实现学生信息的注册功能。这个应用可能包括创建HTML表单、处理用户输入、验证数据以及存储或展示提交的信息。JavaScript...

    simple_show:SimpleShow 是 #show 就像 SimpleForm 是 #edit

    SimpleShow 是#show,就像SimpleForm 是#edit 一样。 要求: 导轨 3 安装: 将其添加到您的 Gemfile 中: gem "simple_show" 更新您的捆绑包: bundle update simple_show 运行生成器: rails generate ...

    Firefox自动表单,火狐自动表单,火狐插件fillform

    FillForm功能概要描述及与普通填表扩展autofill forms的比较: * 通过一个快捷键(Alt + Q)就可以填写当前网页内容。 * 通过一个快捷键(Alt + W)就可以保存当前网页内容,这是autofill forms所没有的功能。 * ...

    一个画流程图的Delphi控件 v2.90

    《Delphi控件实现流程图绘制:SimpleGraph v2.90详解》 在软件开发过程中,流程图是一种直观表达程序逻辑和系统流程的重要工具。本文将深入探讨一个基于Delphi开发的流程图控件——SimpleGraph v2.90,它是一个开源...

    simple_form_recurring_select:包装用于SimpleForm的“ recurring_select” gem

    gem 'simple_form_recurring_select' 然后执行: $ bundle 或将其自己安装为: $ gem install simple_form_recurring_select 用法 在模型中: class MyModel include SimpleFormRecurringSelect :: ...

    Simpleflow工作流引擎V20071227(已发布了更新的版本)(附一个支付报销流程样例)

    Simpleflow工作流引擎是一款在IT领域广泛应用的流程管理工具,尤其在Domino Lotus环境中,它为组织提供了高效、灵活的工作流自动化解决方案。该版本V20071227在原有基础上进行了重要更新,增强了流程管理和数据归档...

    SimpleMail的理解与思考

    SimpleMail的理解与思考 一个用于发送邮件的简单程序

    jQuery+css 流程图插件

    在压缩包文件中,"simpleFlow"可能包含以下组件: 1. **CSS文件**:定义流程图及各节点的样式,例如`syle.css`。 2. **JavaScript文件**:包含流程图插件的核心逻辑,如`flowchart.js`,可能包括初始化流程图、添加...

    Simple Contact Form Using HTML JavaScript.zip

    标题 "Simple Contact Form Using HTML JavaScript.zip" 涉及到的是一个基础的网页表单设计,其中使用了HTML和JavaScript技术。在这个项目中,开发者创建了一个简易的联系表单,以便访客能方便地向网站所有者发送...

    simplegraph2.62

    "SimpleGraph 2.62" 是一个由外籍开发者创建的图形绘制工具,主要用于创建流程图。这个控件设计用于软件开发,特别是那些需要在用户界面中集成绘图功能的应用程序。SimpleGraph 提供了一个简单易用的接口,使得...

    delphi 流程图控件源码+demo

    6. SimpleGraph.pas:这是Delphi的源代码文件,包含了流程图控件的主要实现代码。 7. ReadMe.htm:这是常见的说明文件,通常包含如何使用、安装或配置资源的指导信息。 8. SimpleGraph.res:这是Delphi的资源文件,...

    simple_form_validation:简单的表单验证提供验证格式并返回结果

    simple_form_validation 简单的表单验证提供验证格式并返回结果介绍它仅验证输入值。特征简单的只有JavaScript 仅提供价值验证并返回结果开发人员可以处理形式验证中的逻辑用法方法必需(validateInput,errorMsg) ...

    REdis命令处理流程处理分析

    它们的共同点均是通过REdis的简单事件驱动(AE,A simple event-driven)触发,对于Linux实际是epoll的包装,对于macOS为evport的包装,对于FreeBSD对kqueue的包装,对于其它则是select的包装。

Global site tag (gtag.js) - Google Analytics