views:

284

answers:

3

What is the best way to share common objects between multiple views in an MVC application? Say I have a LoginController that takes a user name and password and authenticates the user and loads their data (account info, full name, etc.). I want to display this on each page - something like a header with "Welcome <user name>, you have <account value> in your account." I don't think I should just store that user object in session. Do I have to return it with each controller?

I'm using the Spring framework for this application, but I don't think that matters. There must be some generic way to handle this common use case.

Update

Not sure if this matters, but I also need the UserID (a primary key returned upon login) as a parameter into other controllers. As this is just another value on the user object returned but not displayed, I would think the answer would be the same as data that is displayed.

+1  A: 

If there's quite a lot of logic associated with the common elements, it may be easier to perform a sub-request using ServletRequest.getRequestDispatcher() aka <jsp:include />, then you can go through the whole request processing cycle again with a "Sub-Controller" and "Sub-View".

EDIT: look at Spring MVC HandlerInterceptors

Ramon
A: 

I've handled this exact use case before in a Spring MVC application by having a HandlerInterceptor (Javadoc link) add these details to the ModelAndView for all pages in which I needed it.

Since the whole purpose of a HandlerInterceptor is to be able to have common functionality applied to many requests and/or responses by a single piece of code, this is a natural fit. An Interceptor allows you to hook into either the pre- or post-handle step of a Controller; and you can configure your UrlHandlerMapping to only apply the interceptor to certain URLs (or patterns of URLs) if you wish.

matt b
That looks to help with common logic, but how do I access the user information from the HandlerInterceptor? I have to store it somewhere accessible to the HandlerInterceptor accross all views, right?
David Buckley
Yes. If you are using Spring Security, then the current principal for the thread is easily available (statically, which might feel odd) - SecurityContextHolder.getContext().getAuthentication().getPrincipal()
matt b
+2  A: 

You're not really sharing common objects - this is common data (and yes, wrapped by an object). Lets say you have a minimal UserInfo class and a corresponding template fragment that displays it. That fragment will be included in your views.

But regardless of the framework (and how you add this common fragment to your views) the framework/template engine will need to find a 'userInfo' binding and get the required fields.

Unless you are planning on hitting your (db) back-end on every page request to get that information, you will need to cache it. Typically this will be in the session.