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()方法,进行业务逻辑处理

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

 

你可能感兴趣的:(spring,Web,mvc,servlet,struts)