在Spring MVC中设置全局模型属性的最佳实践是什么?

时间:2011-01-10 21:09:48

标签: spring spring-mvc

我有一个数据驱动(缓存)的菜单,它是一个全局组件。我希望能够为每个请求注入菜单项,因为每个页面都将使用它。什么是最好的地方?我正在使用基于注释的Spring3。我能想到的最佳解决方案是使用OncePerRequestFilter并在那里添加或对Controller进行子类化,但不知道如何使用@Controller注释来做到这一点。

5 个答案:

答案 0 :(得分:13)

我可以想到两个简单的选择:

每个@Controller类都将数据公开为使用@ModelAttribute注释的方法,例如

@ModelAttribute
public MyData getMyData() {
  ...
}

但是如果你有多个控制器,这并不是很好。此外,这会产生令人讨厌的副作用,即将myData编码为每次重定向的URL

我建议改为实现HandlerInterceptor,并将数据公开给每个请求。你不能使用任何注释-lovin,但它最好以这种方式与你的业务逻辑分开。这类似于您的OncePerRequestFilter想法,但更多的是Spring-y。

答案 1 :(得分:10)

答案 2 :(得分:7)

启动Spring 3.2,您可以使用@ControllerAdvice而不是在每个Controller中使用@ExceptionHandler,@ InitBinder和@ModelAttribute。它们将应用于所有@Controller bean。

import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.context.request.WebRequest;

@ControllerAdvice
public class GlobalBindingInitializer {
  @InitBinder
  public void registerCustomEditors(WebDataBinder binder, WebRequest request) {
    binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
  }
}

如果您刚开始使用Spring Roo生成的代码,或者使用include-filter限制组件扫描扫描的注释,那么在webmvc-config.xml中添加所需的过滤器

<!-- The controllers are autodetected POJOs labeled with the @Controller annotation. -->
<context:component-scan base-package="com.sensei.encore.maininterface" use-default-filters="false">
  <context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
  <!-- ADD THE BELOW LINE -->
  <context:include-filter expression="org.springframework.web.bind.annotation.ControllerAdvice" type="annotation"/>
</context:component-scan>

答案 3 :(得分:1)

我刚刚找到了同一个问题的答案。这是我帖子的一部分:

Is there a way to stop Spring from adding in reference data from methods marked with @ModelAttribute into the URL on redirects?

您只需要在RedirectView上将expose model属性变量设置为false。

答案 4 :(得分:0)

如果需要添加一些全局变量,每个视图都可以解析这些变量,为什么不定义属性或映射?然后使用spring DI,请参阅视图解析器bean。它非常有用,例如静态可靠,例如resUrl。

<property name="viewResolvers">
    <list>
        <bean
    class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="viewClass"
                value="org.springframework.web.servlet.view.JstlView" />
            <property name="attributes" ref="env" />
            <property name="exposeContextBeansAsAttributes" value="false" />
            <property name="prefix" value="${webmvc.view.prefix}" />
            <property name="suffix" value="${webmvc.view.suffix}" />
        </bean>
    </list>
</property>