Spring considère que tout ce qui se trouve derrière le dernier point est une extension de fichier telle que .json
or .xml
et la tronquer pour récupérer votre paramètre.
Donc si vous avez /somepath/{variable}
:
/somepath/param
, /somepath/param.json
, /somepath/param.xml
Ou /somepath/param.anything
se traduira par une valeur avec paramparam
/somepath/param.value.json
, /somepath/param.value.xml
ou /somepath/param.value.anything
entraînera un paramètre avec une valeurparam.value
si vous modifiez votre mappage /somepath/{variable:.+}
comme suggéré, tout point, y compris le dernier, sera considéré comme faisant partie de votre paramètre:
/somepath/param
se traduira par un paramètre avec une valeur param
/somepath/param.json
se traduira par un paramètre avec une valeur param.json
/somepath/param.xml
se traduira par un paramètre avec une valeur param.xml
/somepath/param.anything
se traduira par un paramètre avec une valeur param.anything
/somepath/param.value.json
se traduira par un paramètre avec une valeur param.value.json
- ...
Si vous ne vous souciez pas de la reconnaissance des extensions, vous pouvez la désactiver en mvc:annotation-driven
remplaçant automagic:
<bean id="handlerMapping"
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
<property name="contentNegotiationManager" ref="contentNegotiationManager"/>
<property name="useSuffixPatternMatch" value="false"/>
</bean>
Donc, encore une fois, si vous avez /somepath/{variable}
:
/somepath/param
, /somepath/param.json
, /somepath/param.xml
Ou /somepath/param.anything
se traduira par une valeur avec paramparam
/somepath/param.value.json
, /somepath/param.value.xml
ou /somepath/param.value.anything
entraînera un paramètre avec une valeurparam.value
remarque: la différence avec la configuration par défaut n'est visible que si vous avez un mappage comme somepath/something.{variable}
. voir problème du projet Resthub
si vous souhaitez conserver la gestion des extensions, depuis Spring 3.2, vous pouvez également définir la propriété useRegisteredSuffixPatternMatch du bean RequestMappingHandlerMapping afin de garder la reconnaissance suffixPattern activée mais limitée à l'extension enregistrée.
Ici, vous définissez uniquement les extensions json et 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>
Notez que mvc: annotation-driven accepte désormais une option contentNegotiation pour fournir un bean personnalisé mais la propriété de RequestMappingHandlerMapping doit être changée en true (false par défaut) (cf. https://jira.springsource.org/browse/SPR-7632 ).
Pour cette raison, vous devez toujours remplacer la configuration entièrement mvc: basée sur les annotations. J'ai ouvert un ticket pour Spring pour demander un RequestMappingHandlerMapping personnalisé: https://jira.springsource.org/browse/SPR-11253 . Veuillez voter si vous êtes intercepté.
Lors de la substitution, soyez prudent de considérer également la substitution de la gestion d'exécution personnalisée. Sinon, tous vos mappages d'exceptions personnalisés échoueront. Vous devrez réutiliser messageCoverters avec un bean list:
<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>
J'ai implémenté, dans le projet open source Resthub dont je fais partie, un ensemble de tests sur ces sujets: voir https://github.com/resthub/resthub-spring-stack/pull/219/files & https: // github.com/resthub/resthub-spring-stack/issues/217