使用Spring MVC在所有控制器中执行相同的操作

时间:2015-04-27 12:47:21

标签: spring hibernate jsp spring-mvc authentication

问题很简单:一旦用户在我的Spring MVC应用程序中进行了身份验证,我想在导航菜单中显示所有未读消息的计数,每个页面中的

对于特定页面,我可以在其控制器中执行此操作:

@RequestMapping(value = "/some/url", method = RequestMethod.GET)
public String somePage(Model model, Principal principal) {

    // Count messages and add to the view
    int countMessages = userService.countAllUnreadMessages(principal.getName());
    model.addAttribute("countMessages", countMessages);
    // ...

    return "some/view";
}

问题是如何避免在每个控制器的所有方法中执行相同的调用?有没有办法将数据参数传递给所有页面的视图? (当然,所有页面都不包括/login形式)

4 个答案:

答案 0 :(得分:2)

您可以使用controller advice,定义一个@ModelAttribute带注释的方法,将消息计数添加到模型中。

答案 1 :(得分:2)

您可以使用拦截器来实现相同的功能。在Interceptor中一次又一次地编写要调用的代码段,以及要排除调用方法映射的所有代码在排除映射路径中。

<mvc:interceptor>
    <mvc:mapping path="/**"/>
    <mvc:exclude-mapping path="/login/**"/>
    <bean class="com.test.yourInterceptorClass" />
</mvc:interceptor>

答案 2 :(得分:1)

您可以在用户登录后将属性存储在会话中,并从页面访问会话变量。您可以使用@SessionAttributes("countMessages")对控制器类进行注释,这将在会话中存储您的值,并将其放入模型中。页面将通过${countMessages}以与访问模型变量相同的方式访问它。

您也可以明确地使用会话,例如

@RequestMapping(value = "/some/url", method = RequestMethod.GET)
public String somePage(Model model, Principal principal, HttpSession session) {

    // Count messages and add to the view
    int countMessages = userService.countAllUnreadMessages(principal.getName());
    model.addAttribute("countMessages", countMessages);
    session.addAttribute("countMessages", countMessages);
    // ...

    return "some/view";
}

但请注意,会话回答了问题的这一部分有没有办法将数据参数传递给所有页面的视图?现在每当有更改的数量时消息读取你也必须更新会话值,你可以通过再次调用这个控制器方法来做。

其他答案提供了一种在没有显式调用的情况下自动更新计数的方法,可以通过拦截请求或在@ModelAttribute上调用@ControllerAdvice带注释的方法,这可能更适合您的问题

答案 3 :(得分:0)

有多种方法可以达到你想要的效果。 我建议您使用自定义过滤器,它将用作“装饰器”,并将添加您想要的数据。

public class MessagesFilter implements Filter{

@Override
public void destroy() {
    // Do nothing
}

@Override
public void doFilter(ServletRequest req, ServletResponse res,
        FilterChain chain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;

        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

       int countMessages = userService.countAllUnreadMessages(authentication.getName());
        req.addAttribute("countMessages", countMessages);

        chain.doFilter(req, res);

}

@Override
public void init(FilterConfig arg0) throws ServletException {
    // Do nothing
}

}

public class MessagesFilter extends GenericFilterBean{
@Override
public void doFilter(ServletRequest request, ServletResponse response,
        FilterChain chain) throws IOException, ServletException {
    //Implement this Function to have your filter working
}

请参阅此answer以获取正确的示例