在JavaSpringMVC中具有相同的方法调用并在所有(或我的大多数)控制器中设置属性

在JavaSpringMVC中具有相同的方法调用并在所有(或我的大多数)控制器中设置属性,java,spring,spring-mvc,Java,Spring,Spring Mvc,几乎在我所有的页面中都有一个侧边栏,它需要一些方法和查询才能执行(比如说其中的城市和事件列表)。所以基本上,现在我在几乎所有的控制器中调用该方法,然后调用model.setAttribute(“mylist”,list) 对我来说,一个好的解决方案是,当我将侧边栏子页面包含在JSP中时,如果我可以为它调用一个控制器或服务,但在视图层中这是不可能的。我能做的就是将Java代码片段放在JSP子页面中,并包含在所有页面中,这很糟糕 现在我正在添加这些方法调用,并在所有控制器中设置结果属性,这是大量重复

几乎在我所有的页面中都有一个侧边栏,它需要一些方法和查询才能执行(比如说其中的城市和事件列表)。所以基本上,现在我在几乎所有的控制器中调用该方法,然后调用model.setAttribute(“mylist”,list)

对我来说,一个好的解决方案是,当我将侧边栏子页面包含在JSP中时,如果我可以为它调用一个控制器或服务,但在视图层中这是不可能的。我能做的就是将Java代码片段放在JSP子页面中,并包含在所有页面中,这很糟糕

现在我正在添加这些方法调用,并在所有控制器中设置结果属性,这是大量重复代码。对于这些情况,什么是好的设计解决方案


总之:我想在几乎所有的控制器中都有一些方法调用,因为在Apache Tiles中,我使用了一个侧边栏子页面,需要在控制器/服务层中完成这些方法调用。

如果我正确回答了您的问题,您需要一些列表对象,其值需要显示在左侧/右侧的所有视图页面中

若列表值(从中填充列表的表)不经常更改,那个么您可以点击查询一次并只准备一次列表,然后您可以将该列表设置为会话变量,以便您可以在视图层直接获取它


基于您正确的需求,如果这不起作用,您可以选择一些类似的需求

如果您需要的是大多数视图中的附加模型属性,我会选择@ControllerAdvice注释。在那里,您可以声明带有@modeldattribute注释的方法,并且在每次控制器调用时都会调用该方法


这可能会导致一些开销,因此请保持简单和快速;)

另一个选项是向MVC配置中添加拦截器。例如,此拦截器检索用户的未读对话数,以便在导航栏中显示该对话,并将其作为请求范围的属性存储在HttpServletRequest中。也可以将其添加到ModelAndView中:

public class PageModelInterceptor extends HandlerInterceptorAdapter {
    private MessagingService mailboxService;

    public PageModelInterceptor() {
    }

    @Override
    public void postHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler, final ModelAndView modelAndView) {
        addNbConversationUpdates(request);
    }

    private void addNbConversationUpdates(final HttpServletRequest request) {
        if (XSecurity.principal() != null) {
            final int nbUpdatedConversations = mailboxService.getUpdatedConversations(XSecurity.principal().getId()).size();
            request.setAttribute("nbConversationUpdates", nbUpdatedConversations);
        }
    }

    public void setMailboxService(final MessagingService mailboxService) {
        this.mailboxService = mailboxService;
    }
}
这需要添加到dispatcher-servlet.xml或web应用程序上下文声明的任何文件中

<mvc:interceptor>
    <mvc:mapping path="/ui/**" />
    <bean class="com.xyz.project.web.PageModelInterceptor">
        <property name="mailboxService" ref="mailboxService" />
    </bean>
</mvc:interceptor>


正如您所见,您可以声明一个路径模式,从而排除不必要的URL。

这可能会以基于意见的方式关闭,但是:在控制器之间冷使用继承。另外,请阅读SiteMesh(旧但仍在工作)或ApacheTiles之类的装饰程序。是的,我目前正在使用ApacheTiles,我的页面中包含了一个侧栏JSP。但这是一个JSP,我不能在JSP之前调用控制器,对吗?不过继承可能是个好主意,嗯,考虑一下。将它放在应用程序或会话范围是我想到的。但我还是需要在所有的控制器中这样做,因为我不知道它们将首先到达哪个页面。所以我希望它是一种无状态的,在每个控制器上我只做方法调用。正如你所说的,几乎所有页面都需要它,所以我想到了这一点。您仍然可以选择基于URL模式加载列表之类的方式。如果您需要在某些xyz页面中显示侧边栏,那么您可以选择一些url模式,如果出现,则加载列表并保持就绪。“基于url模式加载列表”您的意思是我可以在这些url上使用类似Contoller的过滤器?我的意思是说,例如“/dashboard1”、“/dashboard2”如果你想显示侧栏,那么你可以发送一个请求,比如“sideBar/dashborad1”,“sideBar/dashborad2”,现在你只需查看URL模式,检查请求是否带有加载列表中的“sideBar”模式,并做好准备,以便下次不需要再次点击。比如@RequestMapping,你可以稍微探索一下,你将能够操纵它。SpringMVC将在这方面帮助您。