0

Using spring MVC, I need to store my object into session and I should use the same object in several jsp pages using jstl. I have tried like this:

ModelAndView modelAndView = new ModelAndView("admin/addproduct", "category", categorynameList); 

But I can't access the category to other jsp pages except addproduct page.

How can I do that?

4 Answers 4

2

Spring MVC provides more than one mechanisms that hide the plain use of HttpSession from you.

Have a look at the @SessionAttributes annotation, which allows you to define the attributes that will be stored in the session by your controller; this mechanism is mainly intended to maintain the conversational state for your handler and that state is usually cleared once the conversation is complete.

Also, you can define your bean as session scoped in the application context and then make use of a ScopedProxyFactoryBean (by simply adding an <aop:scoped-proxy/> element in your bean definition), thus being able to inject that bean in your singleton controllers.

Sign up to request clarification or add additional context in comments.

2 Comments

I am afraid @SessionAttributes is meant to keep data between requests of one particular handler, across the life of this handler only. The documentation says "session attributes used by a specific handler". See claymitchell.net/2008/02/11/…
You're right; thanks ! I'll edit my answer to point that out.
1

You can pass the session directly to any annotated controller method:

@RequestMapping("somePathName") public String someHandler(HttpSession session) { session.setAttribute(... 

Comments

0

The annotation @SessionAttributes is used on class level. Typically it's used on the @Controller class. It's 'value' element is of type String[] whose values are the matching names used in @ModelAttribute either on method level or on handler's method parameter level.

Let's consider following arrangement:

@Controller @SessionAttributes("visitor") @RequestMapping("/trades") public class TradeController { @ModelAttribute("visitor") public Visitor getVisitor (....) { return new Visitor(....); } .... } 

In above code, when a request comes in, the first thing Spring will do is to notice @SessionAttributes('visitor') and then attempt to find the value of 'visitor' in javax.servlet.http.HttpSession. If it doesn't find the value, then the method with @ModelAttribute having the same name 'visitor' (method getVisitor()) will be invoked. The returned value from such method will be used to populate the session with name 'visitor'.

Now that 'visitor' with it's value is already in HttpSession, let's consider following arrangement:

@Controller @SessionAttributes("visitor") @RequestMapping("/trades") public class TradeController { @RequestMapping("/**") public String handleRequestById (@ModelAttribute("visitor") Visitor visitor, Model model, HttpServletRequest request) { model.addAttribute("msg", "trades request, serving page " + request.getRequestURI()); visitor.addPageVisited(request.getRequestURI()); return "traders-page"; } ....... } 

On finding @ModelAttribute("visitor") in the target handler method, Spring will retrieve the value of 'visitor' from the session and will assign the value to the Visitor parameter and will invoke the method. At this step, Spring doesn't care how the session was populated with 'visitor', Whether it was populated using the last arrangement or some other way, it doesn't matter, Spring only requires the annotation @SessionAttributes('visitor'), the handler method parameter with @ModelAttribute("visitor") and the value of 'visitor' in HttpSession. If spring can't find it in the session and last arrangement is not available then following exception will be thrown:

org.springframework.web.HttpSessionRequiredException: Expected session attribute 'visitor'

In other words: when the target handler method is invoked first time in a given session, then method with @ModelAttribute('visitor) is invoked, the returned value is populated in HttpSession and the handler method with the same value is invoked. For the subsequent requests within the same HTTPSession, Spring retrieves the same object from the session and doesn't call the method with @ModelAttribute('visitor') again till the end of the session

Following is the complete controller class:

@Controller @SessionAttributes("visitor") @RequestMapping("/trades") public class TradeController { @RequestMapping("/**") public String handleRequestById (@ModelAttribute("visitor") Visitor visitor, Model model, HttpServletRequest request) { model.addAttribute("msg", "trades request, serving page " + request.getRequestURI()); visitor.addPageVisited(request.getRequestURI()); return "traders-page"; } @ModelAttribute("visitor") public Visitor getVisitor (HttpServletRequest request) { return new Visitor(request.getRemoteAddr()); } } 

In above example we are tracking the user visited pages within the same HTTP session. We are using the wildcard '/**' so that all request starting with 'trades' will map to this controller.

1 Comment

(Welcome to (finally) posting on SO!) You will have seen code snippets standing out (surrounded by `` "backticks") - where the is a chance of ambiguity, do the same (or everywhere for consistency - speaking of which: use the Java string delimiter " around Java String literals).
-2

Inject session to your controller classes, store your object there and use it when you need it, e.g.:

@Controller public class SomeController { //@Autowired //private HttpSession session; This is not desired. See the discussion in the //comments. @RequestMapping("somePathName") public String someHandler(HttpSession session) { //Session will be injected by //Spring without any additional annotations. //... session.setAttribute("category", yourObject); } } 

If you need to access category on other pages than admin/addproduct you will need to add it to respective models as follows:

@RequestMapping("somePathName") public String someHandler(Model model) { //... model.addAttribute("category", yourObject); //... return "yourPageName"; } 

Update: according to ALex's comment that injecting HttpSession instance into field is strongly not desired due to thread safety concerns I've changed the source respectively.

9 Comments

I would not recommend this approach. Controllers are reused across requests so should not have state. Inject it into a specific controller method.
What's the difference between injecting into field and method? Functionally, this doesn't change anything but in the first case you will have less to write.
If the controller is a singleton (which it is by default) and you store the session in a private variable it'll be available to all requests for all users. You want to access a specific users session for the scope of a request i.e. for the scope of a single call to a controller method.
Session doesn't make sense in request scope. Besides, AFAIK, every user can only access her own session.
A session does make sense in the request scope. You access a session from the HttpServletRequest.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.