带点(。)的Spring MVC @PathVariable正在被截断

这是Spring MVC @PathVariable被截断的问题的延续

Spring论坛指出它已经修复(3.2版本)作为ContentNegotiationManager的一部分。 看下面的链接。
https://jira.springsource.org/browse/SPR-6164
https://jira.springsource.org/browse/SPR-7632

在我的应用程序与.com的requestParameter被截断。

任何人都可以解释我如何使用这个新function? 它是如何configuration在XML?

注意:

http://forum.springsource.org/showthread.php?137000-Spring-MVC-PathVariable-with-dot-(-)-is-getting-truncated&p=444607#post444607

据我所知这个问题只出现在请求映射结束的pathvariables。

我们能够通过在requestmapping中定义正则expression式插件来解决这个问题。

/somepath/{variable:.+} 

Spring认为最后一个点后面的任何内容都是文件扩展名,例如.json或.xml然后用trucate来检索你的参数。

所以如果你有/somepath/{variable}

  • /somepath/param/somepath/param /somepath/param.json/somepath/param /somepath/param.xml/somepath/param.anything将会产生一个参数值param
  • /somepath/param.value.json/somepath/param.value.anything将产生一个param值为param.value

如果您按照build议将映射更改为/somepath/{variable:.+} ,则包含最后一个点的任何点都将被视为参数的一部分:

  • /somepath/param将会产生一个param值为param
  • /somepath/param.json将会产生一个param值为param.json的参数
  • /somepath/param.xml将生成一个param值为param.xml的参数
  • /somepath/param.anything将导致一个参数的值param.anything
  • /somepath/param.value.json将产生一个param值为param.value.json的参数

如果您不关心扩展识别,可以通过覆盖mvc:annotation-driven来禁用它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> 

所以,再一次,如果你有/somepath/{variable}

  • /somepath/param/somepath/param /somepath/param.json/somepath/param /somepath/param.xml/somepath/param.anything将会产生一个参数值param
  • /somepath/param.value.json/somepath/param.value.anything将产生一个param值为param.value

注意:只有在像somepath/something.{variable}这样的映射somepath/something.{variable} ,与默认configuration的区别才是可见的。 请参阅Resthub项目问题

如果你想保持扩展pipe理,从Spring 3.2开始,你也可以设置RequestMappingHandlerMapping bean的useRegisteredSuffixPatternMatch属性,以保持后缀模式识别的激活,但限于注册扩展。

在这里你只定义了json和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> 

请注意,mvc:annotation-driven现在接受一个contentNegotiation选项来提供一个自定义Bean,但RequestMappingHandlerMapping的属性必须更改为true(默认为false)(参见https://jira.springsource.org/browse/SPR-7632 )。

因此,您仍然必须覆盖所有mvc:注释驱动的configuration。 我打开了Spring的一张票,要求一个自定义的RequestMappingHandlerMapping: https : //jira.springsource.org/browse/SPR-11253 。 如果你是在英国,请投票。

在压倒一切时,也要考虑自定义执行pipe理覆盖。 否则,所有的自定义exception映射都将失败。 您将不得不重复使用messageCoverters与列表bean:

 <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> 

我在Resthub这个开源项目中实现了一个关于这些主题的testing: https: //github.com/resthub/resthub-spring-stack/pull/219/files&https :// github.com/resthub/resthub-spring-stack/issues/217

除了Martin Frey的回答之外,还可以通过在RequestMapping值中添加一个斜杠来解决这个问题:

 /path/{variable}/ 

请记住,此修补程序不支持可维护性。 它现在要求所有的URI都有一个尾部的斜线 – 这对API用户/新开发者来说可能并不明显。 因为它可能不是所有的参数可能有一个. 在他们中间,也可能造成间歇性的错误

Spring 4更新:自4.0.1以来,您可以使用PathMatchConfigurer (通过您的WebMvcConfigurer ),例如

 @Configuration protected static class AllResources extends WebMvcConfigurerAdapter { @Override public void configurePathMatch(PathMatchConfigurer matcher) { matcher.setUseRegisteredSuffixPatternMatch(true); } } 

在xml中,它将是( https://jira.spring.io/browse/SPR-10163 ):

 <mvc:annotation-driven> [...] <mvc:path-matching registered-suffixes-only="true"/> </mvc:annotation-driven> 

添加“:。+”为我工作,但直到我删除外大括号。

值= { “/username/{id:.+}” } 不起作用

值=“/username/{id:.+}”的作品

希望我帮助了一个人:)

/somepath/{variable:.+}在Java requestMapping标记中起作用。

这是一个完全依赖于javaconfiguration的方法:

 import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; @Configuration public class MvcConfig extends WebMvcConfigurationSupport{ @Bean public RequestMappingHandlerMapping requestMappingHandlerMapping() { RequestMappingHandlerMapping handlerMapping = super.requestMappingHandlerMapping(); handlerMapping.setUseSuffixPatternMatch(false); handlerMapping.setUseTrailingSlashMatch(false); return handlerMapping; } } 

解决此问题的一个非常简单的方法是追加一个尾部斜杠…

例如:

使用 :

 /somepath/filename.jpg/ 

代替:

 /somepath/filename.jpg 

包括电子邮件地址在path名称为spring4.2的完整的解决scheme是

 <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> <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager"> <mvc:path-matching suffix-pattern="false" registered-suffixes-only="true" /> </mvc:annotation-driven> 

将此添加到application-xml

如果你使用Spring 3.2.x和<mvc:annotation-driven /> ,创build这个小BeanPostProcessor

 package spring; public final class DoNotTruncateMyUrls implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof RequestMappingHandlerMapping) { ((RequestMappingHandlerMapping)bean).setUseSuffixPatternMatch(false); } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } } 

然后把这个在你的MVCconfigurationXML:

 <bean class="spring.DoNotTruncateMyUrls" /> 

在Spring Boot中,正则expression式解决了这个问题

 @GetMapping("/path/{param1:.+}") 

在Spring Boot中,我通过以下步骤解决了这些问题:RestController:

@GetMapping("/statusByEmail/{email:.+}") public List<Map<String, Object>> statusByEmail(@PathVariable(value = "email") String email)

和从rest客户端:

Get http://webhook.gsikder.com/statusByEmail/abc.test@gmail.com/