带点(。)的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/