2010-07-12 6 views
18

Es sollte einfach sein:Wie registriere ich Handler Interzeptoren mit Feder mvc 3.0?

<bean id="handlerMapping" 
    class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"> 
    <property name="interceptors"> 
     <list> 
      <ref bean="myInterceptor" /> 
     </list> 
    </property> 
</bean> 

aber auf diese Weise die Abfangjäger wird nicht aufgerufen.

+2

Haben Sie auch '' dort irgendwo? – skaffman

+0

Ja, um javax.validation handling zu aktivieren (und vielleicht einen Haufen anderer Dinge) – Bozho

Antwort

29

Standardmäßig registriert Spring eine BeanNameUrlHandlerMapping und eine DefaultAnnotationHandlerMapping, ohne dass eine explizite Konfiguration erforderlich ist.

Wenn Sie Ihre eigenen HandlerMapping Beans definieren, werden die Standardbeans nicht registriert, und Sie erhalten nur die explizit deklarierten Beans.

So weit, so gut. Das Problem tritt auf, wenn Sie <mvc:annotation-driven/> zum Mix hinzufügen. Diese auch deklariert eine eigene DefaultAnnotationHandlerMapping, die die Standardwerte ersetzt. Wenn Sie jedoch auch Ihre eigene deklarieren, enden Sie mit zwei. Da sie in der Reihenfolge der Deklaration konsultiert werden, bedeutet dies normalerweise, dass die von <mvc:annotation-driven/> registrierte Person zuerst angerufen wird und Ihre eigene ignoriert wird.

Es wäre besser, wenn die DefaultAnnotationHandlerMapping, die von <mvc:annotation-driven/> registriert wird, sich wie die Standardfunktion verhält, d. H. Wenn explizit deklarierte Vorrang haben, aber das ist nicht die Art, wie sie geschrieben wurde.

Meine aktuelle Präferenz ist es, <mvc:annotation-driven/> überhaupt nicht zu verwenden, es ist zu verwirrend und zu unvorhersehbar, wenn es mit anderen Konfigurationsoptionen gemischt wird. Es macht nicht wirklich etwas besonders Komplexes, es ist nicht schwierig oder ausführlich, das Zeug, das es für dich tut, explizit hinzuzufügen, und das Endergebnis ist einfacher zu folgen.

+0

Gute Erklärung. es als akzeptiert markieren. Ich werde eine andere Frage stellen mit dem, was unklar bleibt - d. H. Wie Teile davon aktiviert werden, was mvc: annotation-driven tut. – Bozho

+3

https://jira.springsource.org/browse/SPR-6524 scheint es gibt ein Problem dafür, und Jürgen Hoeller Kommentare, dass dies beabsichtigt ist. – Bozho

+0

'' - keine Notwendigkeit für eine andere Frage :) – Bozho

9

Der Grund für dieses Verhalten ist, dass zwei Beans des Typs org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping im Anwendungskontext vorhanden sind. Spring löst die beiden auf, fragt aber nur den ersten nach Interzeptoren. Um dies zu beheben, sollte die folgende Init-Parameter eingestellt werden, um die DispatcherServlet

<init-param> 
    <param-name>detectAllHandlerMappings</param-name> 
    <param-value>false</param-value> 
</init-param> 

Diese Verwendung der Dispatcher Servlet macht nur die handlerMapping im definierten x-servlet.xml

Es ist mir unbegreiflich, warum dies das Standardverhalten ist. Ich erwarte eine Antwort von der Frühlingsgemeinschaft.

+3

Die Standardwerte bei der Verwendung des '' Namespace sind sehr verwirrend. Ich bevorzuge die ältere Art, alles selbst zu spezifizieren - die Namespace-Konfigurationsmethoden scheinen sich zu sehr auf nicht-einfach-gefunden-in-Dokumentationsstandards –

3

Im Frühling MVC 3.0 können Sie <mvc:interceptors> anstelle der manuellen Definition der Handler-Zuordnung verwenden.

+2

+1 zu verlassen, das ist gut. Aber ich kann 'ref' dort nicht verwenden. – Bozho

+1

@Bozho: Sie können eine 'BeanReferenceFactoryBean' verwenden (ja, ich weiß, dass es hässlich ist). – axtavt

+0

Ja, es ist :) Ich denke, ich bleibe jetzt bei meiner Lösung. – Bozho

12

Problem ich konfrontiert: Spring MVC-Tag nicht gut mit benutzerdefinierten Definition von DefaultAnnotationHandlerMapping.

Warum ..? Der Grund wird in den obigen Antworten sehr gut erklärt.

Warum wollte ich DefaultAnnotationHandlerMapping benutzen? Ich möchte für jede Anfrage einen Interceptor definieren. ein Spring-Mobile Interceptor, um den USER AGENT..mobile oder einen Browser zu ermitteln?

Jetzt Aufgrund dieses Zusammenprall der mvc-Annotation und DefaultAnnotationHandlerMapping, kippe ich DefaultAnnotationHandlerMapping mehr verwenden. Das Problem kommt darauf an, wie ich meine Interzeptoren mit Tag registrieren kann.

Die Lösung war einfach ... aber schwer zu finden. Posting es so kann es hilfreich sein zu den anderen Lösung Suchern .. Verwenden Tag und registriert die Abfangjäger Bohne in Ihrem dispathcer-servlet.xml Beispiel:

<mvc:interceptors> 
<!-- This runs for all mappings --> 
    <bean class="main.com.XXX.MobileDeviceResolverHanlderInterceptor"/> 
</mvc:interceptors> 
+0

Vielen Dank, sehr nützlich! +1 – ianaz

+0

Ich habe diese Tags bereits in meine 'xxx-servlet.xml'-Datei geschrieben, aber immer noch mit dem Fehler konfrontiert. –

+0

Danke Mann, du hast wirklich geholfen –

6

In meinem Fall kann ich nicht loswerden <mvc:annotation-driven/> wie ich Jackson für json Unterstützung mit Annotation verwenden.

Was ich versuchte, zog meine alle Abfangjäger <mvc:interceptors> in separaten "xml" Datei (Interceptor-config.xml) und importiert es aus meiner x-Dispatcher-servlet.xml

<import resource="interceptor-config.xml"/> 

Es ist mein Problem zu lösen und Vermeiden Sie Default 'DefaultAnnotationHandlerMapping' beans meinen Anwendungskontext.

Anstatt separate 'xml' zu erstellen, können Sie Interceptor-Inhalte direkt in 'x-dispatcher-servlet.xml' kopieren/einfügen.

Es folgt mein Interceptor:

<mvc:interceptors> 
     <mvc:interceptor> 
      <!-- Intercepting specific URL --> 
      <mvc:mapping path="/abc/**" /> 
      <bean id= "myInterceptor" 
       class="xx.xxx.xxx.MyInterceptor" /> 
     </mvc:interceptor> 
<mvc:interceptors>