2011-01-10 22 views
14

Tengo un menú basado en datos (en caché) y es un componente global. Quiero poder insertar los elementos del menú para cada solicitud, ya que cada página va a usarlo. ¿Cuál es el mejor lugar para ponerlo? Estoy usando la anotación basada en Spring3. La mejor solución que se me ocurre es usar un filtro OncePerRequest y agregarlo allí o subclasificar el controlador, pero no estoy seguro de cómo hacerlo con la anotación @Controller.¿Cuáles son las mejores prácticas para establecer los atributos del modelo global en Spring MVC?

Respuesta

13

puedo pensar en dos opciones fáciles:

Cada clase @Controller expone los datos como un método anotado con @ModelAttribute , p.ej

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

Sin embargo, eso no es muy bueno si tienes varios controladores. Además, esto tiene el molesto efecto secundario de codificar el myData en la URL para cada redirección

Sugiero que implemente un HandlerInterceptor y exponga los datos a cada solicitud de esa manera. No puede usar ninguna anotación-lovin, pero está mejor separada de la lógica de su negocio de esta manera. Esto es similar a su idea OncePerRequestFilter, pero una pero más Spring-y.

+3

+1 por mencionar el efecto secundario de ModelAttribute. Desearía que alguien me hubiera dicho eso antes :(Gracias por la dirección. –

7

Al iniciar Spring 3.2, puede usar @ControllerAdvice en lugar de utilizar @ExceptionHandler, @InitBinder y @ModelAttribute en cada controlador. Se aplicarán a todos los beans @Controller.

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)); 
    } 
} 

Si había comenzado con Spring Roo Código generado, o limitar las anotaciones escaneados por componentes de escaneo usando include-filtro, a continuación, añadir el filtro requerido en 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> 
+0

También puede ser un enlace útil sobre '@ ControllerAdvice' en' Spring 4': http://blog.codeleak.pl/2013/11/controlleradvice- mejoras-en-primavera.html – Andremoniy

0

Si necesita agregar algunas variables globales para que cada vista pueda resolver estas variables, ¿por qué no definirlas en un mapa o propiedades? Entonces use la primavera DI, refiérase al bean resolvedor de vista. es muy útil, como veriable estático, p. 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> 
Cuestiones relacionadas