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

问题

这是问题Spring MVC @PathVariable getting truncated的延续

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

在我的应用程序中,带有.com的requestParameter被截断。

谁能解释我如何使用这个新功能?它是如何在xml中配置的?

注:spring forum- #1 Spring MVC @PathVariable with dot (.) is getting truncated


#1 热门回答(400 赞)

据我所知,此问题仅出现在请求映射结束时的path变量上。

我们能够通过在请求映射中定义正则表达式插件来解决这个问题。

/somepath/{variable:.+}

#2 热门回答(212 赞)

Spring认为最后一个点后面的任何内容都是文件扩展名,例如.json.xml,并将其设置为检索你的参数。

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

  • / somepath / param,/ somepath / param.json,/ somepath / param.xml或/somepath/param.anything将导致带有值param的参数
  • /somepath/param.value.json,/somepath/param.value.xml或/somepath/param.value.anything将生成一个值为param.value的param

如果你将建议的映射更改为/somepath/{variable:.+},则任何点(包括最后一个点)都将被视为参数的一部分:

  • / somepath / param将导致带有值param的param
  • /somepath/param.json将生成一个值为param.json的param
  • /somepath/param.xml将生成一个值为param.xml的param
  • /somepath/param.anything将导致param值为param.anything
  • /somepath/param.value.json将生成一个值为param.value.json的param
  • ......

如果你不关心扩展程序识别,可以通过覆盖mvc:annotation-drivenautomagic禁用它:

<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.json,/ somepath / param.xml或/somepath/param.anything将导致带有值param的参数
  • /somepath/param.value.json,/somepath/param.value.xml或/somepath/param.value.anything将生成一个值为param.value的param

注意:仅当你具有类似somepath/something.{variable}的映射时,才能看到与默认配置的差异。 seeResthub project issue

如果你想保持扩展管理,从Spring 3.2开始你也可以设置RequestMappingHandlerMapping bean的useRegisteredSuffixPatternMatch属性,以便使suffixPattern识别被激活,但仅限于注册的扩展。

在这里,你只定义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)(cf.https://jira.springsource.org/browse/SPR-7632)。

因此,你仍然必须覆盖所有mvc:annotation驱动的配置。我打开了一张Spring的票,要求自定义RequestMappingHandlerMapping:https://jira.springsource.org/browse/SPR-11253。如果你在这里,请投票。

在覆盖的同时,还要考虑自定义执行管理覆盖。否则,所有自定义的异常映射都将失败。你将不得不将messageCoverters与list 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中实现了对这些主题的一系列测试:seehttps://github.com/resthub/resthub-spring-stack/pull/219/fileshttps://github.com/resthub/resthub-spring-stack/issues/217


#3 热门回答(85 赞)

Spring 4的更新:从4.0.1开始,你可以使用PathMatchConfigurer(通过yourWebMvcConfigurer),例如:

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