0

I'm creating a Spring application and in it I have a side bar which can be use to access modules of the application.

The side bar remains visible through out all views of the application. I create the view using Apache Tiles.

Since I don't want to hard code the menu items in the JSP, I want to populate required data(Link name, URL pattern) from database.

I want to do this only once so my plan is to create a session bean to put all these menu details in to it.

I create a Class called "MenuDAO" and I autowire it to the controller. Then I create a method to return that "MenuDAO" object and I mark it as a "ModelAttribute" in my controller.

@Autowired
private MenuDAO menuDAO;

@ModelAttribute("userDetails")
public UserDetail getUserDetail(){
    return this.userDetails;
}

Now I am wandering where can I fill this DAO with data. I want to do it once per session(like when user logged in).

I cannot do it in the method with request mapping because once it get called Model attributes are already injected so only when the page loads next time the new data will be available.

Again I thought of doing it inside a method annotated with @PostConstruct. But then I need to do it in every Controller.

So I want to know where I can do this correctly so that I can populate this bean once per user session.

dharam
  • 7,882
  • 15
  • 65
  • 93
Susitha Ravinda Senarath
  • 1,648
  • 2
  • 27
  • 49
  • Is it a valid thing to be done? I mean I find a cyclic dependency, based on the user you populate the menu and you wont know the user till you hit the controller's request mapping. Isn't it? – dharam Aug 26 '13 at 11:48
  • Well err yes. I need to populate the menu depend on the user. Once user is authenticated he is redirected to the "/home" url mapping. OK then I need to load menu details there is it? But since ModelAttributes are already injected before loading menu details view gets a empty session bean. So side bar doesn't have any links at this point. From there since the session object with populated data next time ModelAttribute is injecting the session bean with data. Now I have links. How to overcome this?? – Susitha Ravinda Senarath Aug 26 '13 at 14:29
  • 1
    I'd suggest you do it how jpprade described, but otherwise @PostConstruct in session bean should work. If you use Spring Security you can also create a bean that implements ApplicationListener and listen for AuthenticationSuccessEvent and then do whatever you want when user logs in. – Krešimir Nesek Aug 27 '13 at 07:11
  • I tried with ApplicationListener but thhe issue there is since session is not available at that time I cannot create "MenuDAO" object and push it to the session. – Susitha Ravinda Senarath Aug 28 '13 at 05:55

2 Answers2

0

Check this question it is quite similar : Dynamic content in all page in Spring MVC

You will have to populate your modelAndView in a postHandle method of an interceptor. The interceptors are called for every request so it is your responsability to not call your dao for every request.

I would suggest you to store your menu in a cache instead of putting it in the session (using ehcache which is easy to set up in spring) .

Community
  • 1
  • 1
jpprade
  • 3,497
  • 3
  • 45
  • 58
0

I solve it as follows. I don't feel that this is the most convenient way. But it works.

I autowire session bean and mark required attribute as model attrbutes.

@Autowired
private MenuDAO menuDAO;

@ModelAttribute("menuDetails")
public List<ElabModuleWebProperties> getMenuDetails(){
    return this.menuDAO.getMenuList();
}

After authenticate I redirect to url patter "home" by Spring Security. In that method I check whether the session bean has initialized and if not I do it there.

@RequestMapping(value = "home", method = RequestMethod.GET)
public String showHome(ModelMap model, Principal principal){
    logger.debug("User accessing home");
    if(!menuDAO.isMenuInitiationDone()){
        logger.debug("menuDAO is empty, populating data for the object");
        menuDAO.setMenuList(loginService.loadUserDetailsByUsername(SecurityContextHolder.getContext().getAuthentication().getName()));
        menuDAO.setMenuInitiationDone(true);
    }
    model.put("menuDetails", menuDAO.getMenuList());
    return "welcome";
}

In other controllers I can just autowire the bean and use it. No problem.

Susitha Ravinda Senarath
  • 1,648
  • 2
  • 27
  • 49