O Spring considera que qualquer coisa por trás do último ponto é uma extensão de arquivo, como .json
ou .xml
e truncar-lo para recuperar o seu parâmetro.
Então, se você tem /{blahName}
:
/param
, /param.json
, /param.xml
Ou /param.anything
irá resultar em uma param com valorparam
/param.value.json
, /param.value.xml
ou/param.value.anything
resultará em um parâmetro com valorparam.value
Se você alterar seu mapeamento para /{blahName:.+}
o sugerido, qualquer ponto, incluindo o último, será considerado como parte do seu parâmetro:
/param
resultará em um parâmetro com valor param
/param.json
resultará em um parâmetro com valor param.json
/param.xml
resultará em um parâmetro com valor param.xml
/param.anything
resultará em um parâmetro com valor param.anything
/param.value.json
resultará em um parâmetro com valor param.value.json
- ...
Se você não se importa com o reconhecimento de extensão, pode desativá-lo substituindo mvc:annotation-driven
automagic:
<bean id="handlerMapping"
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
<property name="contentNegotiationManager" ref="contentNegotiationManager"/>
<property name="useSuffixPatternMatch" value="false"/>
</bean>
Então, novamente, se você tiver /{blahName}
:
/param
, /param.json
, /param.xml
Ou /param.anything
irá resultar em uma param com valorparam
/param.value.json
, /param.value.xml
ou /param.value.anything
resultará em um parâmetro com valorparam.value
Nota: a diferença da configuração padrão é visível apenas se você tiver um mapeamento semelhante /something.{blahName}
. Consulte Problema do projeto Resthub .
Se você deseja manter o gerenciamento de extensões, desde o Spring 3.2, também é possível definir a propriedade useRegisteredSuffixPatternMatch do bean RequestMappingHandlerMapping para manter o reconhecimento do sufixoPattern ativado, mas limitado à extensão registrada.
Aqui você define apenas extensões json e 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>
Observe que o mvc: driven-anotation agora aceita uma opção contentNegotiation para fornecer um bean personalizado, mas a propriedade RequestMappingHandlerMapping deve ser alterada para true (padrão false) (consulte https://jira.springsource.org/browse/SPR-7632 )
Por esse motivo, você ainda precisa substituir toda a configuração orientada a anotações do mvc: Abri um ticket para o Spring para solicitar um RequestMappingHandlerMapping personalizado: https://jira.springsource.org/browse/SPR-11253 . Por favor vote se você estiver interessado.
Ao substituir, tome cuidado para considerar também a substituição personalizada do gerenciamento de Execução. Caso contrário, todos os seus mapeamentos de exceção personalizados falharão. Você precisará reutilizar messageCoverters com um 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>
Eu implementei, no projeto de código aberto Resthub do qual faço parte, um conjunto de testes sobre esses assuntos: consulte https://github.com/resthub/resthub-spring-stack/pull/219/files e https: // github.com/resthub/resthub-spring-stack/issues/217