Announcement Announcement Module
Collapse
No announcement yet.
Spring MVC and sessions Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring MVC and sessions

    Hello everybody,
    I am looking at the Spring framework for a future project. I wrote a small web application to get familiar with the Sping Framework.

    Does Spring contain any session management? For example standard servlets contain HttpSessions.
    The problem is that when I don't use HttpSessions the information of different users gets mixed up. I tought Spring MVC would take care of the session management. I looked in the Spring documentation but didn't find it.
    I have tried a lot of different things with for example sessionForm, requireSession, ...

    I can post my code if it is helpful.


    Kind regards,

    Jannes Van de maele

  • #2
    Not exactly understand your problem, you can use the standard httpRequest and HttpSession. These are available to you in the controllers. But that is probably not what you mean. Some code will make that more clear i think. So give it to us all :-)

    Comment


    • #3
      Spring MVC and sessions

      Ok I am sorry, I will make myself a bit more clear.
      This is the problem: I browse to my application and search for a person with the id 'p1'. The name of 'p1' is displayed and the extra information on this person is stored in a bean. Now a second person (so with a different session/sessionId) searches for a person 'p2'. If the first person now refreshes his page he gets the information of the second search (p2). This is clearly a problem with sessions and shared context. I tought that Spring MVC would couple a bean to a session, but it just uses one bean and overwrites its content.

      Here is the code of my example.

      Any help is very much appreciated!

      Jannes Van de maele



      ==============================================
      ==============================================

      xml
      ---


      <beans>

      <bean id="search" class="be.kzen.training.springwebsimple.viewmodel. Search">
      <property name="title"><value>Geef hier de persoon id in</value></property>
      </bean>

      <bean id="person" class="be.kzen.training.springwebsimple.model.Pers on">
      </bean>

      <bean id="personSearchController" class="be.kzen.training.springwebsimple.controller s.PersonSearchController" singleton="true">
      <property name="search"><ref bean="search"/></property>
      </bean>

      <bean id="personResultController" class="be.kzen.training.springwebsimple.controller s.PersonResultController" singleton="true">
      <property name="sessionForm"><value>true</value></property>
      <property name="commandName"><value>search</value></property>
      <property name="commandClass"><value>be.kzen.training.spring websimple.viewmodel.Search</value></property>
      <property name="search"><ref bean="search"/></property>
      <property name="person"><ref bean="person"/></property>
      </bean>

      <bean id="personResultJustNameController" class="be.kzen.training.springwebsimple.controller s.PersonResultJustNameController" singleton="true">
      <property name="sessionForm"><value>true</value></property>
      <property name="commandName"><value>person</value></property>
      <property name="commandClass"><value>be.kzen.training.spring websimple.model.Person</value></property>
      <property name="person"><ref bean="person"/></property>
      </bean>

      <bean id="viewResolver" class="org.springframework.web.servlet.view.Intern alResourceViewResolver">
      <!--<property name="viewClass"><value>org.springframework.web.se rvlet.view.JstlView</value></property>-->
      <property name="prefix"><value>/</value></property>
      <property name="suffix"><value>.jsp</value></property>
      </bean>

      <bean id="simpleUrlMapping" class="org.springframework.web.servlet.handler.Sim pleUrlHandlerMapping">
      <property name="mappings">
      <props>
      <prop key="PersonSearch.asl">personSearchController</prop>
      <prop key="PersonResult.asl">personResultController</prop>
      <prop key="PersonResultJustName.asl">personResultJustNam eController</prop>
      </props>
      </property>
      </bean>

      </beans>





      searchcontroller
      ----------------

      public class PersonSearchController extends AbstractController {

      private Search search;

      public Search getSearch() {
      return search;
      }

      public void setSearch(Search search) {
      this.search = search;
      }

      protected ModelAndView handleRequestInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
      return new ModelAndView("PersonSearch", "search", search);
      }
      }




      search.jsp
      ----------

      <html>

      <head>
      <title>spring - training</title>
      <link href="style.css" rel="stylesheet" type="text/css">
      </head>

      <body>
      <h3>${search.title}</h3>
      <form METHOD="post" action="PersonResult.asl">
      <input type="text" name="personId" value=""/><input type="submit" value="begin"/>
      </form>
      </body>

      </html>



      personresultcontroller
      ----------------------

      public class PersonResultController extends SimpleFormController {

      private Search search;
      private Person person;

      public Search getSearch() {
      return search;
      }

      public void setSearch(Search search) {
      this.search = search;
      }

      public Person getPerson() {
      return person;
      }

      public void setPerson(Person person) {
      this.person = person;
      }

      protected ModelAndView onSubmit(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object command, BindException bindException) throws Exception {

      Search tempSearch = (Search)command;
      tempSearch.setTitle(search.getTitle());
      search = tempSearch;
      Persons persons = new Persons();
      Person tempPerson = persons.getPerson(search.getPersonId());
      person.setId(tempPerson.getId());
      person.setName(tempPerson.getName());
      return new ModelAndView("PersonResult", "person", person);

      }

      }



      personresult.jsp
      ----------------

      <html>

      <head>
      <title>spring - training</title>
      <link href="style.css" rel="stylesheet" type="text/css">
      </head>

      <body>
      <h3>${person.id}</h3>
      <h3>${person.name}</h3>
      <form METHOD="post" action="PersonResultJustName.asl">
      <input type="submit" value="show just name"/>
      </form>
      </body>

      </html>

      Comment


      • #4
        First a short reply, would it help if you make your object a non-singleton object. Since you refer to a domain object, these should never be singleton. Use the property singleton=false on your bean definition.

        The fact that you overwrite information does not have anything to do with the session. It has everything to do with the spring container that is only loaded once per jvm.

        I had another look at your code, the default value for singleton = true, so you need to mention it explicitly if you want it to have the value false. You set it to true everywhere, that looks like you think the defualt is false.

        Hope this helps

        Comment


        • #5
          Spring MVC and sessions

          It doesn't fix the problem I'm afraid. I've tried it and it gives the same result.
          I use Tomcat as application server and it makes only one instance of the bean in stead of a bean per session.
          I would think that the controller class can identify the instance of a bean with the sessionId it gets from the HttpRequest.

          I can make this example work when I use the HttpSession and in the controller class always put the beans on the session. But this feels a bit like a work arround and so the Spring MVC isn't used optimal. I hoped that Spring MVC had some kind of session management.

          Thanks in advance,

          Jannes Van de maele

          Comment


          • #6
            Come to think of it, that is not that strange. The personResultController is a singleton, the person is injected at startup time only. You need to do something with getBean(...); or just create the domain object with the new operator. But that does not solve your session object. To be honest I do not see it as a workaround to store objects in the session if you want to keep a reference to it. I think the SimpleFormController does something simular if you set the right property to session. This controller also stores beans in the session. But that is just my opinion :-). Maybe someone reading this can share their opinion as well.

            Comment


            • #7
              That is actualy what I am looking for. The right property for the SimpleFormController so that I don't have to put my beans on the sessions myself.
              And a problem that goes together with this is the validation. When I put a validation property-tag in my wiring I assume that it will use what's defined in the command class to validate. But if I use HttpRequest my command object is still on the HttpSession.
              Is there a way to get my object from the HttpSession before it gets validated?

              Thanks!

              Jannes Van de maele

              Comment


              • #8
                As jettro mentioned, Controllers are by default singletons. YOu should not store any state in your Controllers, as you have done when you do: search = tempSearch;

                Form controllers can store the command objects in the session, but only between the initial GET and POST. To understand this you must understand that form controllers model a form request lifespan, from initial viewing of the form through form submission. After the form is submitted, the form controller's job is done, and it will remove the command object from the session.

                So, to keep the command object in the session between form workflows you will need to manage the session manually. Spring's form controllers do not have the equivalent of Strut's scope="session", which keeps the same form bean in the session for the life of the session.

                Now, if you need to keep objects in the session during the lifespan of the session, Spring 1.3 will include this functionality. Only instead of just managing command beans, it will manage any type of object. This functionality is useful to have user session scoped beans.

                Hope that helps.

                BTW, you could store state in your controller, but you will need to set singleton="false". This does not, however, solve your problem with storing command beans in the session for the lifespan of the session.

                Comment


                • #9
                  The property I meant is discussed in the javadoc of formBackingObject:

                  <p>Note that you need to activate session form mode to reuse the form-backing
                  * object across the entire form workflow. Else, a new instance of the command
                  * class will be created for each submission attempt, just using this backing
                  * object as template for the initial form.

                  Comment


                  • #10
                    jettro, good point.

                    I do want to make it clear that "entire form workflow" means only intial GET, any validation errors, and final form submission (POST). After a clean POST, the object is removed from session. *


                    * technically before then, but end result is the same.

                    Comment


                    • #11
                      Think of a controller as a servlet. Servlets are only loaded once, as are controllers.

                      You can also store state in ThreadLocals - but this should not be designed in. Having to store state in the controller is, IMO, bad design. There are always exceptions where it is necessary, but it should not be part of the design.

                      Think of the abstractions - a controller represents the application, an HttpSession represents the user. So where should the user's state be stored?

                      Bob

                      Comment


                      • #12
                        How do I activate the session form mode?

                        Thanks in advance.

                        Comment


                        • #13
                          set sessionForm to true on your controller.

                          Comment


                          • #14
                            Code:
                            <bean id="myFormController" class="com.mycom.controller.MyFormController">
                                <property name="commandName"><value>myCommand</value></property>
                                <property name="commandClass"><value>com.mycom.command.MyCommand</value></property>
                                <property name="sessionForm"><value>true</value></property>
                            </bean>
                            Bob

                            Comment

                            Working...
                            X