【问题标题】:Work flow of simpleFormcontroller in spring MVC 3.0spring MVC 3.0中simpleFormcontroller的工作流程
【发布时间】:2012-10-11 06:07:23
【问题描述】:

我见过很多关于simpleFormcontroller 工作原理的例子。

但我还是有些困惑。

我想知道formBackingObject()referenceData()onSubmit() 方法何时被调用?

我不知道这些方法的具体工作流程?

谁能解释一下?

【问题讨论】:

    标签: spring spring-mvc controller


    【解决方案1】:

    工作流程如下,由AbstractFormController类控制-

    1. 控制器收到新表单的请求(通常是 GET)。
    2. 调用 formBackingObject(),默认情况下会返回已配置的 commandClass 实例(参见超类公开的属性),但也可以被覆盖例如从数据库中检索一个对象(需要使用表单进行修改)。
    3. 调用 initBinder(),它允许您为命令类的某些字段(通常是非原始或非字符串类型的属性)注册自定义编辑器。这将为这些属性值呈现适当的字符串,例如特定于语言环境的日期字符串。
    4. 仅当 bindOnNewForm 设置为 true 时,才会应用 ServletRequestDataBinder 以使用初始请求参数填充新表单对象,并调用 onBindOnNewForm(HttpServletRequest, Object, BindException) 回调方法。注意:此时不应用任何定义的验证器,以允许部分绑定。但是请注意,通过 initBinder() 应用的任何 Binder 自定义(例如 DataBinder.setRequiredFields(String[]) 仍然适用。因此,如果使用 bindOnNewForm=true 和 initBinder() 自定义)验证字段而不是使用验证器,如果只为新表单填充一些字段,则错误对象中缺少字段可能会出现一些绑定错误。任何显示绑定错误的视图(JSP 等)都需要要智能,在这种情况下,请考虑是显示初始表单视图还是显示后续发布结果,跳过前者的错误显示。
    5. 调用 showForm() 以返回应呈现的视图(通常是呈现表单的视图)。此方法必须在子类中实现。
    6. showForm() 实现将调用 referenceData(),您可以实现它以提供您在编辑表单时可能需要的任何相关参考数据(例如您要让用户从中选择一个的语言环境对象)。
    7. 模型被暴露,视图被渲染,让用户填写表单。
    8. 控制器接收表单提交(通常是 POST)。要使用不同的方式检测表单提交,请覆盖 isFormSubmission 方法。
    9. 如果未设置 sessionForm,则调用 formBackingObject() 来检索表单对象。否则,控制器会尝试查找已经绑定在会话中的命令对象。如果找不到对象,它会调用 handleInvalidSubmit - 默认情况下 - 尝试创建新的表单对象并重新提交表单。
    10. ServletRequestDataBinder 被应用以使用当前请求参数填充表单对象。
    11. 调用 onBind(HttpServletRequest, Object, Errors) 允许您在绑定之后但验证之前进行自定义处理(例如,手动将请求参数绑定到 bean 属性,以供验证器查看) .
    12. 如果设置了 validateOnBinding,将调用已注册的验证器。 Validator 将检查表单对象的属性,并通过给定的 Errors 对象注册相应的错误。
    13. 调用 onBindAndValidate() 允许您在绑定和验证之后进行自定义处理(例如手动绑定请求参数,并在验证器之外验证它们)。
    14. 调用 processFormSubmission() 来处理提交,无论是否存在绑定错误。此方法必须在子类中实现。

    Source

    有关更多详细信息和图表表示以了解流程,您可以参考以下链接 -

    【讨论】:

      【解决方案2】:

      SimpleFormController 自 Spring 3.0 起已弃用

      在 Spring 3.0 中,使用一个控制器和两种方法用于创建过程(第三种方法用于显示页面)。典型的样子是这样的:

      /**
       * Shows a form for car creation.
       */
      @RequestMapping(params = "form", method = RequestMethod.GET)
      public ModelAndView createForm() {
          ModelMap uiModel = new ModelMap();
          uiModel.addAttribute("carCreateFormBackingObject", new CarCreateFormBackingObject()); //formBackingObject - often called command object
          uiModel.addAttribute("manufactureres", this.manufactureresDao.readAll()); //referenceData
          return new ModelAndView("car/create", uiModel);
      }
      
      /**
       * Creates the car and redirects to its detail page.
       *
       */
      @RequestMapping(method = RequestMethod.POST)
      public ModelAndView create(final @Valid CarCreateFormBackingObject carCreateFormBackingObject,
              final BindingResult bindingResult) {
      
          if (bindingResult.hasErrors()) {
                      ModelMap uiModel = new ModelMap();
              uiModel.addAttribute("carCreateFormBackingObject", carCreateFormBackingObject);
              uiModel.addAttribute("manufactureres", this.manufactureresDao.readAll()); //referenceData
              return new ModelAndView("car/create", uiModel);
          }
      
          Car car = this.carService.create(carCreateFormBackingObject.name, ...);
          return new ModelAndView(new RedirectView("/cars/" + car.getId(), true)); //redirect to show page
      }
      

      我还想知道 formBackingObject(),refernceData() 方法是由谁以及何时自动调用的?

      回到你的问题“我仍然想知道 formBackingObject(),refernceData() 方法是由谁以及何时自动调用的?”

      所有这些方法都由SimpleFormController(及其超类AbstractFormController)调用,遵循模板-方法-模式。 - SimpleFormController 在该流程的一些钩子中定义流程和您的具体子类“插件”以获得业务价值。

      • formBackingObject 在控制器需要处理提交 (POST) 或为初始“新”视图构建 Command 对象时由 AbstractFormController 调用。

      • referenceData 在需要为视图构建模型时始终调用AbstractFormController

      【讨论】:

        【解决方案3】:

        formBackingObject() 方法,用于在渲染页面之前执行一些操作。即类似于 HTML 组件中的默认值。

        refereceData() 方法,用于在表单中添加参考数据,即填充下拉列表

        OnSubmit() 方法,在您提交表单时调用。

        但是,如果您使用的是 Spring 3.0 使用注释遵循以下方法

        @RequestMapping(value = "/index.htm", method = RequestMethod.GET)
        public String showLogin() {
            return "user/login";
        }
        

        这将与 formBackingObject 相同。并在此方法中使用 modelMap() 并添加参考数据。

        添加方法的方式与 method = POST 相同,与 OnSubmit() 相同

        【讨论】:

        • 嗨 Vinit,感谢您的回答。我仍然想知道 formBackingObject(),refernceData() 方法由谁以及何时自动调用?
        【解决方案4】:

        【讨论】:

        • 单独的链接是considered a poor answer,因为它本身没有意义,并且不能保证目标资源将来仍然存在。 It would be preferable 在这里包含答案的基本部分,并提供链接以供参考。
        • “目标资源不能保证在未来仍然存在” - 所以我们应该将我们需要的所有内容粘贴到 SO =) 还有 MSDN 完整 =)
        【解决方案5】:

        FormBackingObjectMethod()---> @RequestMapping(requestMethod.GET) 而第一次显示在屏幕上的表单 formBackingObject 是原因

        initBinder()---> 通常用于假设你想要的日期字段应该是例如(自定义日期示例:dd**MM***yyyy)需要意味着使用 initBinder 方法

        onSubmit() -->@RequestMapping(requestMethod.POST) 在提交表单时调用 onSubmit() 方法

        希望对你有帮助

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-25
          • 1970-01-01
          • 1970-01-01
          • 2012-06-26
          相关资源
          最近更新 更多