15

I want to read a domain object (UserVO) from session scope.

I am setting the UserVO in a controller called WelcomeController

@Controller
@RequestMapping("/welcome.htm")
public class WelcomeController {
@RequestMapping(method = RequestMethod.POST)
    public String processSubmit(BindingResult result, SessionStatus status,HttpSession session){
      User user = loginService.loginUser(loginCredentials);
     session.setAttribute("user", user);
         return "loginSuccess";
    }
}

I am able to use the object in jsp pages <h1>${user.userDetails.firstName}</h1>

But I am not able to read the value from another Controller,

I am trying to read the session attribute as follows:

@Controller
public class InspectionTypeController {
@RequestMapping(value="/addInspectionType.htm", method = RequestMethod.POST )
 public String addInspectionType(InspectionType inspectionType, HttpSession session)
 {
           User user = (User) session.getAttribute("user");
           System.out.println("User: "+ user.getUserDetails().getFirstName);

        }
} 
tangens
  • 39,095
  • 19
  • 120
  • 139
binary
  • 1,364
  • 1
  • 15
  • 20

4 Answers4

41

The code you've shown should work - the HttpSession is shared between the controllers, and you're using the same attribute name. Thus something else is going wrong that you're not showing us.

However, regardless of whether or not it works, Spring provides a more elegant approach to keeping your model objects in the session, using the @SessionAttribute annotation (see docs).

For example (I haven't tested this, but it gives you the idea):

@Controller
@RequestMapping("/welcome.htm")
@SessionAttributes({"user"})
public class WelcomeController {
    @RequestMapping(method = RequestMethod.POST)
    public String processSubmit(ModelMap modelMap){
       User user = loginService.loginUser(loginCredentials);
       modelMap.addtAttribute(user);
       return "loginSuccess";
    }
}

and then

@Controller
@SessionAttributes({"user"})
public class InspectionTypeController {

   @RequestMapping(value="/addInspectionType.htm", method = RequestMethod.POST )
   public void addInspectionType(InspectionType inspectionType, @ModelAttribute User user) {
      System.out.println("User: "+ user.getUserDetails().getFirstName);
   }
} 

However, if your original code isn't working, then this won't work either, since something else is wrong with your session.

Hugo Dozois
  • 8,147
  • 12
  • 54
  • 58
skaffman
  • 398,947
  • 96
  • 818
  • 769
  • 1
    I came here looking for the first solution (`@SessionAttributes`) and all I got was `java.lang.IllegalStateException: Cannot create a session after the response has been committed` – Konrad Garus Jan 26 '12 at 07:37
  • 1
    This seems to contradict what @karpaczio says... Can someone confirm which is correct? I would think that session attributes are shared regardless of the `@Controller` in question, but I haven't delved into the inner workings of `@SessionAttribute`. – Andy Feb 06 '13 at 22:20
  • 2
    @Andy See my comment on karpaczio's answer – Denys Kniazhev-Support Ukraine Mar 02 '13 at 17:33
  • @KonradGarus: The `IllegalStateException` is thrown because Tomcat doesn't allow to create a new session after the output has been flushed (because it can no longer set a cookie). And unfortunately, Spring first flushes the output and then tries to move the persistent model attributes to the session. The solution is to force the creation of a session in your controller method: Declare `HttpServletRequest request` in your parameter list and call `request.getSession();`. – Codo Aug 06 '14 at 09:26
6

@SessionAttributes works only in context of particular handler, so attribute set in WelcomeController will be visible only in this controller.

karpaczio
  • 159
  • 1
  • 3
  • 4
  • 6
    What you are saying is the case for Spring versions <= 3.1.2.RELEASE. Starting from 3.1.2.RELEASE, @SessionAttributes are persisted among different controllers as expected – Denys Kniazhev-Support Ukraine Mar 02 '13 at 17:32
  • 2
    @Denis Kniazhev see [here](http://docs.spring.io/spring-framework/docs/3.2.0.M2/api/org/springframework/web/bind/annotation/SessionAttributes.html) Use SessionAttributes for such conversational attributes which are supposed to be stored in the session temporarily during the course of a specific handler's conversation. For permanent session attributes, e.g. a user authentication object, use the traditional session.setAttribute method instead. – Marko Vranjkovic Oct 25 '13 at 14:38
2

Use a parent class to inherit all the controllers and use SessionAttributes over there. Just that this class should be in the package scan of mvc.

0

May be you have not set your UserVO as Serializable.

Anil Bhargava
  • 64
  • 1
  • 4