0

我正在创建一个 Spring 应用程序,其中有一个侧边栏,可用于访问应用程序的模块。

侧栏在应用程序的所有视图中保持可见。我使用 Apache Tiles 创建视图。

由于我不想对 JSP 中的菜单项进行硬编码,因此我想从数据库中填充所需的数据(链接名称、URL 模式)。

我只想这样做一次,所以我的计划是创建一个会话 bean 来将所有这些菜单详细信息放入其中。

我创建了一个名为“MenuDAO”的类,并将其自动连接到控制器。然后我创建一个方法来返回该“MenuDAO”对象,并在我的控制器中将其标记为“ModelAttribute”。

@Autowired
private MenuDAO menuDAO;

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

现在我在徘徊在哪里可以用数据填充这个 DAO。我想每个会话执行一次(例如用户登录时)。

我不能在请求映射的方法中做到这一点,因为一旦它被调用,模型属性就已经被注入,所以只有在下次加载页面时,新数据才可用。

我再次想到在使用@PostConstruct 注释的方法中进行操作。但是我需要在每个控制器中都这样做。

所以我想知道我在哪里可以正确地做到这一点,这样我就可以在每个用户会话中填充一次这个bean。

4

2 回答 2

0

检查这个问题非常相似: Spring MVC中所有页面中的动态内容

您必须在拦截器的 postHandle 方法中填充您的 modelAndView。每个请求都会调用拦截器,因此您有责任不为每个请求调用您的 dao。

我建议您将菜单存储在缓存中,而不是将其放入会话中(使用在春季很容易设置的 ehcache)。

于 2013-08-26T14:04:48.953 回答
0

我解决它如下。我不觉得这是最方便的方式。但它有效。

我自动装配会话 bean 并将所需属性标记为模型属性。

@Autowired
private MenuDAO menuDAO;

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

身份验证后,我通过 Spring Security 重定向到 url 模式“home”。在该方法中,我检查会话 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 并使用它。没问题。

于 2013-09-02T04:40:33.780 回答