Announcement Announcement Module
Collapse
No announcement yet.
How to have a page showing data and as a form at the same time? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • How to have a page showing data and as a form at the same time?

    I would like to have a page as the common layout of a blog page: an article on the top portion of the page and a comment submission form on the bottom of the page. I can't figure out how this can be done with the Spring MVC. To get the data, I need to use a controller to retrieve data from the back end. And to pop up a form, I need to use a SimpleFormController. How to get a SimpleFormController and a Controller work together to show the data and the form. Also, I want to the success view of the SimpleFormController to be the same page.

    Any suggestions?

    Thanks.

  • #2
    Check out the referenceData() method. It's used to load up read-only data for display on web pages.

    Comment


    • #3
      Or, since logically the page being viewed is not the result of a form submission, I prefer to inject an "associated form controller" into my view controller so it can retrieve the form backing object from the form controller to bind the form fields.

      Bob

      Comment


      • #4
        Thanks both for your responses.

        After I posted my initial question, I already thought of retrieving the view data in the referenceData method. As what Bob said, the view data is not a part of form. It might not be the best approach. Bob, can you please tell me how "to inject an 'associated form controller' into my view controller"? I did a quick search and was unable to find the inforamtion.

        Thanks again.

        Comment


        • #5
          Yes, but it's not part of the regular Spring framework. I have my own AbstractFormController and AbstractViewController as part of my own Spring extension library.

          The setup in the application context (the view controller extends AbstractViewController and the form controller extends AbstractFormController):-

          Code:
          <bean id="addProductViewController" class="org.myclient.controller.AddProductViewController">
              <property name="associatedFormController">
                  <ref bean="addProductFormController"/>
              </property>
              <property name="categoryDAO">
                  <ref bean="categoryDAO"/>
              </property>
              <property name="successView"><value>secure/product/addEditProduct</value></property>
          </bean>
              
          <bean id="addProductFormController" class="org.myclient.controller.AddProductFormController">
              <property name="commandName"><value>addEditProductCommand</value></property>
              <property name="commandClass"><value>org.myclient.command.AddEditProductCommand</value></property>
              <property name="sessionForm"><value>true</value></property>
              <property name="validator">
                  <ref bean="commonsValidator"/>
              </property>
              <property name="categoryDAO">
                  <ref bean="categoryDAO"/>
              </property>
              <property name="productDAO">
                  <ref bean="productDAO"/>
              </property>
              <property name="formView"><value>secure/product/addEditProduct</value></property>
              <property name="successView"><value>secure/product/viewProduct</value></property>
          </bean>
          AbstractFormController (abbreviated):-

          Code:
          /*
           * MPSC-Spring - A library of common code to use with the Spring framework
           *
           * Copyright 2005 Matt Parker
           *
           * Licensed under the Apache License, Version 2.0 (the "License");
           * you may not use this file except in compliance with the License.
           * You may obtain a copy of the License at
           *
           *     http://www.apache.org/licenses/LICENSE-2.0
           *
           * Unless required by applicable law or agreed to in writing, software
           * distributed under the License is distributed on an "AS IS" BASIS,
           * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
           * See the License for the specific language governing permissions and
           * limitations under the License.
           */
          package uk.co.mpcontracting.modules.spring.controller;
          
          /**
           * An abstract Spring controller that deals with form submissions
           *
           * @author Matt Parker ([email protected])
           */
          public abstract class AbstractFormController extends SimpleFormController
          {
              private static Log log = LogFactory.getLog(AbstractFormController.class);
              
              private static final String DEFAULT_MESSAGE = "error.standard.defaultMessage";
          
              /**
               * A hook for a sub-class to process the form submission
               *
               * @param request The request
               * @param response The response
               * @param command The associated command object
               * @param errors The current errors collection
               * @return The associated control model
               * @throws Exception If there are any problems with the form processing
               */
              protected abstract ControlModel process(HttpServletRequest request, HttpServletResponse response, Object command,
                  Errors errors) throws Exception;
              
              /**
               * A thread local holder for the form backing object associated with
               * this thread
               */
              private static ThreadLocal formBackingObjectStore = new ThreadLocal();
              
              /**
               * Retrieves the form backing object
               *
               * @param The current request
               * @return The form backing object
               * @throws Exception If there is a problem getting the form backing object
               */
              protected final Object getFormBackingObject(HttpServletRequest request) throws Exception
              {
                  Object formBackingObject = request.getSession().getAttribute(getFormSessionAttributeName(request));
                  
                  if (formBackingObject == null)
                  {
                      formBackingObject = formBackingObjectStore.get();
                  }
                  
                  if (formBackingObject == null)
                  {
                      throw new ServletException("Unable to find form backing object either in session or local store");
                  }
                  
                  return (formBackingObject);
              }
          
              /**
               * Allows an associated view controller to call into the form controller to request
               * that the form backing object is created. This allows Spring bind tags to be used
               * in the view
               *
               * @param request The request
               * @return The form backing object
               * @throws Exception If there is a problem creating the form backing object
               */
              Object createFormBackingObject(HttpServletRequest request) throws Exception
              {
                  if (log.isDebugEnabled())
                  {
                      log.debug("Creating form backing object");
                  }
                  
                  // Clear out any existing commands that may still exist in the session
                  request.getSession().removeAttribute(getFormSessionAttributeName(request));
                  
                  Object formBackingObject = formBackingObject(request);
          
                  request.setAttribute(getCommandName(), formBackingObject);
                  
                  return (formBackingObject);
              }
          }
          AbstractViewController (abbreviated):-

          Code:
          /*
           * MPSC-Spring - A library of common code to use with the Spring framework
           *
           * Copyright 2005 Matt Parker
           *
           * Licensed under the Apache License, Version 2.0 (the "License");
           * you may not use this file except in compliance with the License.
           * You may obtain a copy of the License at
           *
           *     http://www.apache.org/licenses/LICENSE-2.0
           *
           * Unless required by applicable law or agreed to in writing, software
           * distributed under the License is distributed on an "AS IS" BASIS,
           * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
           * See the License for the specific language governing permissions and
           * limitations under the License.
           */
          package uk.co.mpcontracting.modules.spring.controller;
          
          /**
           * An abstract Spring controller that deals with resolving views
           *
           * @author Matt Parker ([email protected])
           */
          public abstract class AbstractViewController implements Controller
          {
              private static Log log = LogFactory.getLog(AbstractViewController.class);
              
              private static final String DEFAULT_MESSAGE = "error.standard.defaultMessage";
              
              /**
               * A hook for a sub-class to process the view request
               *
               * @param request The request
               * @param response The response
               * @return The model and view
               * @throws Exception If there are any problems with the view request
               */
              protected abstract ModelAndView process(HttpServletRequest request, HttpServletResponse response, 
                  Errors errors) throws Exception;
              
              /**
               * A thread local holder for the form backing object associated with
               * this thread
               */
              private static ThreadLocal formBackingObjectStore = new ThreadLocal();
              
              private AbstractFormController associatedFormController;
              
              /**
               * Sets the associated form controller. This allows a view to be associated with a form which in
               * turn allows a form backing object to be created for the view to enable the Spring bind tags
               * to function correctly
               *
               * @param associatedFormController The associated form controller
               */
              public void setAssociatedFormController(AbstractFormController associatedFormController)
              {
                  this.associatedFormController = associatedFormController;
              }
              
              /**
               * Retrieves the associated form controller
               *
               * @return The associated form controller
               */
              protected AbstractFormController getAssociatedFormController()
              {
                  return (associatedFormController);
              }
              
              /**
               * Retrieves the form backing object
               *
               * @return The form backing object
               */
              protected final Object getFormBackingObject()
              {
                  return (formBackingObjectStore.get());
              }
          
              /**
               * Creates a form backing object if required then passes control to the process method
               *
               * @param request The request
               * @param response The response
               * @return The returned model and view
               * @throws Exception If there are any problems with the view request
               */
              public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception
              {
                  // Create a form backing object if we have an associated form
                  if (associatedFormController != null)
                  {
                      // Store in a thread local for possible later retrieval
                      formBackingObjectStore.set(associatedFormController.createFormBackingObject(request));
                  }
                  
                  BindException errors = new BindException("*", "*");
                  ModelAndView modelAndView = process(request, response, errors);
                  
                  if (errors.hasErrors())
                  {
                      modelAndView.addAllObjects(errors.getModel());
                  }
                  
                  return (modelAndView);
              }
          }
          I had to abbreviate the classes to get past the post size limit. My extension code is Apache licensed so if you want to have the whole library then you'd be welcome. It's only at version 0.2 at the moment though and is not yet publically released so I can't guarantee it free from bugs.

          Bob

          Comment


          • #6
            Thanks very much Bob.

            I will study your extension soon. I thought it was done by using AOP somehow. It doesn't seem to be the way after a quick scan of your code.

            BTW, just for my own curiosity, why you don't contribute your code to the Spring framework instead of creating your own branch? I think it is better having the extension inside of the framework so that we can have a collected effort on the code. I might ask too much here. If so, forgive me.

            Comment


            • #7
              Well it is using AOP - the form is being injected via the associatedFormController property.

              As for contributing the extension to Spring, that's up to the Spring maintainers. It's Apache licensed so they will be able to do that if they want. I'm far too busy to maintain it in the Spring framework myself.

              The reason I wrote it is because although I like the AOP aspect of Spring, the MVC component just doesn't quite work in the way I want it to. My main reason for open sourcing it is that I run a consultancy business and wanted to be able to share the code amongst all the projects I work on.

              I'm expecting to release my module publicly sometime early in the New Year. I will annouce it here so if anyone wants a copy they can get one.

              Bob

              Comment

              Working...
              X