我正在创建一个Spring应用程序,在其中我有一个可用于访问应用程序模块的侧栏。
在应用程序的所有视图中,侧栏仍然可见。我使用Apache Tiles创建视图。
由于我不想硬编码JSP中的菜单项,我想从数据库中填充所需的数据(链接名称,URL模式)。
我只想这样做一次,所以我的计划是创建一个会话bean来将所有这些菜单细节放入其中。
我创建了一个名为“MenuDAO”的类,我将它自动装入控制器。然后我创建一个方法来返回“MenuDAO”对象,并在控制器中将其标记为“ModelAttribute”。
@Autowired
private MenuDAO menuDAO;
@ModelAttribute("userDetails")
public UserDetail getUserDetail(){
return this.userDetails;
}
现在我在徘徊在哪里可以用数据填充这个DAO。我希望每个会话执行一次(比如用户登录时)。
我无法在带有请求映射的方法中执行此操作,因为一旦它被调用,模型属性已经被注入,因此只有在下次新数据可用时页面加载时才会这样。
我再次考虑在使用@PostConstruct注释的方法中进行此操作。但是我需要在每个控制器中执行此操作。
所以我想知道我在哪里可以正确地执行此操作,以便每个用户会话可以填充此bean一次。
答案 0 :(得分:0)
检查这个问题它非常相似: Dynamic content in all page in Spring MVC
您必须在拦截器的postHandle方法中填充modelAndView。 每个请求都会调用拦截器,因此您无需为每个请求调用dao。
我建议您将菜单存储在缓存中,而不是将其放入会话中(使用易于在春季设置的ehcache)。
答案 1 :(得分:0)
我按如下方式解决。我不觉得这是最方便的方式。但它确实有效。
我自动装配会话bean并将所需属性标记为模型attrbutes。
@Autowired
private MenuDAO menuDAO;
@ModelAttribute("menuDetails")
public List<ElabModuleWebProperties> getMenuDetails(){
return this.menuDAO.getMenuList();
}
经过身份验证后,我会重定向到url patter&#34; home&#34;由Spring Security提供。在那个方法中,我检查会话bean是否已初始化,如果不是,我在那里做。
@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";
}
在其他控制器中,我可以自动装配bean并使用它。没问题。