2011-01-10 4 views
14

Ich habe ein Menü, das datengesteuert ist (zwischengespeichert) und es ist eine globale Komponente. Ich möchte in der Lage sein, die Menüelemente für jede Anfrage zu injizieren, da jede Seite sie verwenden wird. Was ist der beste Ort, um es zu sagen? Ich verwende Annotation-basierte Spring3. Die beste Lösung, die ich mir vorstellen kann, ist die Verwendung eines OncePerRequestFilter und das Hinzufügen dieser Klasse oder das Unterklassifizieren des Controllers, aber nicht sicher, wie dies mit der @Controller-Annotation zu tun ist.Was sind die besten Vorgehensweisen beim Festlegen globaler Modellattribute in Spring MVC?

Antwort

13

ich von zwei einfachen Möglichkeiten denken kann:

Jede @Controller Klasse, um die Daten als eine Methode mit @ModelAttribute kommentierte aussetzt , z.B

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

Das ist nicht wirklich nett, wenn Sie mehrere Controller haben, obwohl. Dies hat auch den ärgerlichen Nebeneffekt der Codierung der myData auf die URL für jede Umleitung

Ich schlage stattdessen, dass eine HandlerInterceptor implementieren, und die Daten auf jede Anfrage auf diese Weise offen legen. Sie können keine Annotation-Lovin verwenden, aber es ist auf diese Weise besser von Ihrer Geschäftslogik getrennt. Dies ist ähnlich wie Ihre OncePerRequestFilter Idee, aber ein aber mehr Spring-y.

+3

+1 für die Erwähnung der Nebeneffekt von ModelAttribute. Ich wünschte, dass jemand mir das vorher gesagt hatte :(Danke für die Richtung. –

7

Ab Spring 3.2 können Sie anstelle von @ExceptionHandler, @InitBinder und @ModelAttribute in jedem Controller @ControllerAdvice verwenden. Sie werden auf alle @Controller-Beans angewendet.

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

Wenn Sie mit Frühlings-Roo generierten Code begonnen hatte, oder zu begrenzen, die durch die Komponente-Scan gescannt Anmerkungen enthalten Filter verwenden, fügen Sie dann den gewünschten Filter in 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

Kann auch nützlicher Link über '@ ControllerAdvice' in' Frühling 4' sein: http://blog.codeleak.pl/2013/11/controllerradvice- Verbesserungen-im Frühling.html – Andremoniy

0

Wenn Sie einige globale Variablen hinzufügen müssen, die jede Sicht auf diese Variablen auflösen kann, warum definieren Sie nicht in einer Eigenschaft oder Map, dann verwenden Sie Spring DI, siehe View Resolver Bean. es ist sehr nützlich, wie statisch verifizierbar, z.B. 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> 
Verwandte Themen