Spring considera que cualquier cosa detrás del último punto es una extensión de archivo como .json
o .xml
y truncarlo para recuperar su parámetro.
Entonces si tienes /{blahName}
:
/param
, /param.json
, /param.xml
O /param.anything
dará lugar a un parámetro con el valorparam
/param.value.json
, /param.value.xml
o /param.value.anything
dará como resultado un parámetro con valorparam.value
Si cambia la asignación a /{blahName:.+}
lo sugerido, cualquier punto, incluido el último, se considerará parte de su parámetro:
/param
resultará en un parámetro con valor param
/param.json
resultará en un parámetro con valor param.json
/param.xml
resultará en un parámetro con valor param.xml
/param.anything
resultará en un parámetro con valor param.anything
/param.value.json
resultará en un parámetro con valor param.value.json
- ...
Si no le importa el reconocimiento de extensiones, puede deshabilitarlo anulando el mvc:annotation-driven
autómata:
<bean id="handlerMapping"
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
<property name="contentNegotiationManager" ref="contentNegotiationManager"/>
<property name="useSuffixPatternMatch" value="false"/>
</bean>
Entonces, de nuevo, si tienes /{blahName}
:
/param
, /param.json
, /param.xml
O /param.anything
dará lugar a un parámetro con el valorparam
/param.value.json
, /param.value.xml
o /param.value.anything
dará como resultado un parámetro con valorparam.value
Nota: la diferencia con la configuración predeterminada es visible solo si tiene una asignación como /something.{blahName}
. Ver problema del proyecto Resthub .
Si desea mantener la administración de extensiones, desde Spring 3.2 también puede establecer la propiedad useRegisteredSuffixPatternMatch del bean RequestMappingHandlerMapping para mantener activado el reconocimiento de sufijoPattern pero limitado a la extensión registrada.
Aquí solo define las extensiones json y xml:
<bean id="handlerMapping"
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
<property name="contentNegotiationManager" ref="contentNegotiationManager"/>
<property name="useRegisteredSuffixPatternMatch" value="true"/>
</bean>
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="false"/>
<property name="favorParameter" value="true"/>
<property name="mediaTypes">
<value>
json=application/json
xml=application/xml
</value>
</property>
</bean>
Tenga en cuenta que mvc: impulsado por anotaciones acepta ahora una opción contentNegotiation para proporcionar un bean personalizado, pero la propiedad de RequestMappingHandlerMapping debe cambiarse a verdadero (valor predeterminado falso) (cf. https://jira.springsource.org/browse/SPR-7632 )
Por esa razón, aún debe anular toda la configuración mvc: basada en anotaciones. Abrí un boleto a Spring para solicitar un RequestMappingHandlerMapping personalizado: https://jira.springsource.org/browse/SPR-11253 . Por favor vote si le interesa.
Al anular, tenga cuidado de considerar también la anulación de la gestión de ejecución personalizada. De lo contrario, todas sus asignaciones de excepción personalizadas fallarán. Deberá reutilizar messageCoverters con un bean de lista:
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean" />
<util:list id="messageConverters">
<bean class="your.custom.message.converter.IfAny"></bean>
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"></bean>
<bean class="org.springframework.http.converter.StringHttpMessageConverter"></bean>
<bean class="org.springframework.http.converter.ResourceHttpMessageConverter"></bean>
<bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"></bean>
<bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter"></bean>
<bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"></bean>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
</util:list>
<bean name="exceptionHandlerExceptionResolver"
class="org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver">
<property name="order" value="0"/>
<property name="messageConverters" ref="messageConverters"/>
</bean>
<bean name="handlerAdapter"
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="webBindingInitializer">
<bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
<property name="conversionService" ref="conversionService" />
<property name="validator" ref="validator" />
</bean>
</property>
<property name="messageConverters" ref="messageConverters"/>
</bean>
<bean id="handlerMapping"
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
</bean>
Implementé, en el proyecto de código abierto Resthub del que formo parte, un conjunto de pruebas sobre estos temas: consulte https://github.com/resthub/resthub-spring-stack/pull/219/files y https: // github.com/resthub/resthub-spring-stack/issues/217