Re: 在SimpleFormController中用“SessionForm”概念构建修改信息页面

本文探讨了在Spring MVC框架中使用SessionForm模式时覆写formBackingObject方法的方法论,并详细解析了如何在GET请求时将CommandObject放入Session以及POST请求后如何从Session中获取Command对象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

是的,覆写formBackingObject方法就是利用Session Form。使用Session Form还必须将Form设置为Session Form。如下代码末端用红色序号标注的地方表示了通过formBackingObject在“GET"修改页面时将Command Object加入到Session的过程。用绿色序号标注的代码表示了如何在”POST“请求后从Session中取出Command对象。

此段代码拷贝自Spring的AbstractFormController类。


java 代码
 
  1. protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)  
  2.         throws Exception {  
  3.     // Form submission or new form to show?  
  4.     if (isFormSubmission(request)) {  
  5.         // Fetch form object from HTTP session, bind, validate, process submission.  
  6.         try {  
  7.             Object command = getCommand(request);  1
  8.             ...  
  9.         }  
  10.         catch (HttpSessionRequiredException ex) {  
  11.             ...  
  12.         }  
  13.     }  
  14.   
  15.     else {  
  16.         // New form to show: render form view.  
  17.         return showNewForm(request, response); 1 
  18.     }  
  19. }  
  20.   
  21. protected final ModelAndView showNewForm(HttpServletRequest request, HttpServletResponse response)  
  22.         throws Exception {  
  23.   
  24.     logger.debug("Displaying new form");  
  25.     return showForm(request, response, getErrorsForNewForm(request)); 2 
  26. }  
  27.   
  28. protected final BindException getErrorsForNewForm(HttpServletRequest request) throws Exception {  
  29.         // Create form-backing object for new form.  
  30.     Object command = formBackingObject(request); 3 
  31.     if (command == null) {  
  32.         throw new ServletException("Form object returned by formBackingObject() must not be null");  
  33.     }  
  34.     if (!checkCommand(command)) {  
  35.         throw new ServletException("Form object returned by formBackingObject() must match commandClass");  
  36.     }  
  37.   
  38.     // Bind without validation, to allow for prepopulating a form, and for  
  39.     // convenient error evaluation in views (on both first attempt and resubmit).  
  40.     ServletRequestDataBinder binder = createBinder(request, command);  
  41.     BindException errors = new BindException(binder.getBindingResult());  
  42.     if (isBindOnNewForm()) {  
  43.         logger.debug("Binding to new form");  
  44.         binder.bind(request);  
  45.         onBindOnNewForm(request, command, errors);  
  46.     }  
  47.   
  48.     // Return BindException object that resulted from binding.  
  49.     return errors;  
  50. }  
  51.   
  52. protected final Object getCommand(HttpServletRequest request) throws Exception {  
  53.     // If not in session-form mode, create a new form-backing object.  
  54.     if (!isSessionForm()) {  2
  55.         return formBackingObject(request);  
  56.     }  
  57.   
  58.     // Session-form mode: retrieve form object from HTTP session attribute.  
  59.     HttpSession session = request.getSession(false);  
  60.     if (session == null) {  
  61.         throw new HttpSessionRequiredException("Must have session when trying to bind (in session-form mode)");  
  62.     }  
  63.   
  64.     String formAttrName = getFormSessionAttributeName(request);  
  65.     Object sessionFormObject = session.getAttribute(formAttrName);  3
  66.     if (sessionFormObject == null) {  
  67.         throw new HttpSessionRequiredException("Form object not found in session (in session-form mode)");  
  68.     }  
  69.   
  70.     // Remove form object from HTTP session: we might finish the form workflow  
  71.     // in this request. If it turns out that we need to show the form view again,  
  72.     // we'll re-bind the form object to the HTTP session.  
  73.     if (logger.isDebugEnabled()) {  
  74.         logger.debug("Removing form session attribute [" + formAttrName + "]");  
  75.     }  
  76.     session.removeAttribute(formAttrName);  
  77.   
  78.     return currentFormObject(request, sessionFormObject);  
  79. }  
  80.   
  81. protected final ModelAndView showForm(  
  82.     HttpServletRequest request, BindException errors, String viewName, Map controlModel)  
  83.     throws Exception {  
  84.   
  85.     // In session form mode, re-expose form object as HTTP session attribute.  
  86.     // Re-binding is necessary for proper state handling in a cluster,  
  87.     // to notify other nodes of changes in the form object.  
  88.     if (isSessionForm()) { 5 
  89.         String formAttrName = getFormSessionAttributeName(request);  
  90.         if (logger.isDebugEnabled()) {  
  91.             logger.debug("Setting form session attribute [" + formAttrName + "] to: " + errors.getTarget());  
  92.         }  
  93.         request.getSession().setAttribute(formAttrName, errors.getTarget());  6
  94.     }  
  95.   
  96.     ...  
  97. }  
  98.   
  99. protected Object formBackingObject(HttpServletRequest request) throws Exception {  
  100.     return createCommand(); 4 
  101. }  

如此看来覆写formBackingObject方法才是使用Session Form的正道。不过就是好像必须在form初始化时手动设置为Session Form。
现在还没有看出来Session中的Command对象是什么时候被修改的,这还是个问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值