2010-07-12 20 views
18

Debe ser fácil:¿Cómo registrar los interceptores de controlador con spring mvc 3.0?

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

pero de esta manera el interceptor no se llama.

+2

¿Tienes '' en alguna parte? – skaffman

+0

Sí, para activar el manejo de javax.validation (y tal vez un montón de otras cosas) – Bozho

Respuesta

29

De forma predeterminada, Spring registrará un BeanNameUrlHandlerMapping y un DefaultAnnotationHandlerMapping, sin ninguna configuración explícita requerida.

Si define sus propios beans HandlerMapping, los valores predeterminados no se registrarán, y obtendrá los declarados explícitamente.

Hasta ahora, todo bien.

El problema surge cuando agrega <mvc:annotation-driven/> a la mezcla. Este también declara su propio DefaultAnnotationHandlerMapping, que reemplaza los valores predeterminados. Sin embargo, si también declaras el tuyo, terminas con dos. Dado que se les consulta por orden de declaración, esto generalmente significa que se llama primero al registrado por <mvc:annotation-driven/> y se ignora el suyo.

Sería mejor si el DefaultAnnotationHandlerMapping registrado por <mvc:annotation-driven/> actuó como el predeterminado, es decir, si los declarados explícitamente tienen prioridad, pero esa no es la forma en que lo escribieron.

Mi preferencia actual es no usar <mvc:annotation-driven/> en absoluto, es demasiado confuso e impredecible cuando se mezcla con otras opciones de configuración. Realmente no hace nada especialmente complejo, no es difícil ni detallado agregar explícitamente lo que hace por ti, y el resultado final es más fácil de seguir.

+0

Buena explicación. marcándolo como aceptado. Haré otra pregunta con lo que no está claro, es decir, cómo activar partes de lo que está haciendo mvc: anotación. – Bozho

+3

https://jira.springsource.org/browse/SPR-6524 parece que hay un problema para eso, y los comentarios de Juergen Hoeller dicen que esto es así. – Bozho

+0

'' - sin necesidad de otra pregunta :) – Bozho

9

El motivo de este comportamiento es que existen dos beans del tipo org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping en el contexto de la aplicación. Spring resuelve los dos, pero solo pregunta el primero para los interceptores. Para solucionar este problema, el siguiente parámetro init se debe establecer en el DispatcherServlet

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

Esto hace que el uso de servlets despachador sólo el handlerMapping definido en el x-servlet.xml

Es más allá de mí por qué este es el comportamiento predeterminado. Estoy esperando una respuesta de la comunidad de primavera.

+3

Los valores predeterminados cuando se usa el espacio de nombres '' son tremendamente confusos. Prefiero el estilo anterior de especificarlo todo usted mismo: los métodos de configuración del espacio de nombres parecen confiar demasiado en los valores predeterminados de no-fácil-en-documentación –

3

En Spring MVC 3.0 puede usar <mvc:interceptors> en lugar de definir manualmente la asignación del controlador.

+2

+1, eso está bien. Pero no puedo usar 'ref' allí. – Bozho

+1

@Bozho: Puedes usar un 'BeanReferenceFactoryBean' (sí, sé que es feo). – axtavt

+0

sí, es :) Creo que me quedaré con mi solución por ahora. – Bozho

12

Problema que tuve que enfrentar: La etiqueta de Spring MVC no funciona bien con la definición personalizada de DefaultAnnotationHandlerMapping.

¿Por qué ...? el motivo está muy bien explicado en las respuestas anteriores.

por eso que quería utilizar DefaultAnnotationHandlerMapping? Quiero definir un interceptor para todas mis solicitudes. un interceptor de Spring-Mobile para determinar el AGENTE DEL USUARIO ... ¿un móvil o un navegador?

Ahora Debido a este choque de mvc-anotación y DefaultAnnotationHandlerMapping, no puedo utilizar DefaultAnnotationHandlerMapping más. El problema se reduce a cómo puedo registrar mis interceptores con etiqueta.

La solución era simple ... pero difícil de encontrar. Publicarla por lo que puede ser útil a los demás que buscan soluciones .. El uso de etiquetas y registrar el frijol interceptor en su dispathcer-servlet.xml ejemplo:

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

¡Gracias, muy útil! +1 – ianaz

+0

ya estoy poniendo estas etiquetas en mi archivo 'xxx-servlet.xml', pero todavía estoy frente al error. –

+0

Gracias hombre que realmente ayudó –

6

En mi caso no puede deshacerse de <mvc:annotation-driven/> ya que estoy usando jackson para soporte json usando anotación.

Lo he intentado, se ha llevado mi todos los interceptores <mvc:interceptors> en archivo separado "xml" (interceptor-config.xml) e importados desde mi-x-despachador servlet.xml

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

Se resuelve mi problema y evitar los valores predeterminados de 'DefaultAnnotationHandlerMapping' en mi contexto de aplicación.

En lugar de crear separadamente 'xml', puede copiar/pegar contenidos de interceptor directamente en 'x-dispatcher-servlet.xml'.

que sigue es mi interceptor:

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