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

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

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

谁能告诉我如何使用这个新功能?如何在xml中配置它?

注:春季论坛- #1 Spring MVC @PathVariable带点(.)会被截断


当前回答

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

@Configuration
protected static class AllResources extends WebMvcConfigurerAdapter {

    @Override
    public void configurePathMatch(PathMatchConfigurer matcher) {
        matcher.setUseRegisteredSuffixPatternMatch(true);
    }

}


@Configuration
public class WebConfig implements WebMvcConfigurer {

   @Override
   public void configurePathMatch(PathMatchConfigurer configurer) {
       configurer.setUseSuffixPatternMatch(false);
   }
}

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

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

其他回答

对我来说

@GetMapping(path = "/a/{variableName:.+}")

确实工作,但只有当你也编码的“点”在你的请求url为“%2E”,然后它工作。但要求URL都是…虽然有效,但这不是“标准”编码。感觉像是一个bug:|

另一种类似于“后斜杠”的方法是移动带有点“inline”ex的变量:

@GetMapping(path = "/{variableName}/a")

现在所有的点都将被保留,不需要修改。

在Spring Boot中,正则表达式解决了这样的问题

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

Spring认为最后一个点后面的任何东西都是文件扩展名,例如.jsonor .xml,并对其进行构造以检索参数。

如果你有/somepath/{variable}:

/ somepath /参数/ somepath /参数。/somepath/param.xml或/somepath/param. Json。任何参数都会产生一个值为param的参数 / somepath / param.value。/somepath/param.value.xml或/somepath/param.value。任何参数都会产生一个值为param.value的参数

如果您将映射更改为/somepath/{variable:。正如建议的那样,任何点,包括最后一个点都将被视为参数的一部分:

/somepath/param将得到一个值为param的参数 / somepath /参数。Json将产生一个param值为param. Json /somepath/param.xml将产生一个值为param.xml的参数 / somepath /参数。任何参数都会产生值为param. Anything的参数 / somepath / param.value。Json将产生一个param值为param.value. Json ...

如果你不关心扩展识别,你可以通过重写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 /参数/ somepath /参数。/somepath/param.xml或/somepath/param. Json。任何参数都会产生一个值为param的参数 / somepath / param.value。/somepath/param.value.xml或/somepath/param.value。任何参数都会产生一个值为param.value的参数

注意:只有当你有一个类似somepath/something.{variable}的映射时,与默认配置的区别才可见。参见Resthub项目问题

如果你想保持扩展管理,从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:注解驱动的配置。我打开了一个Spring请求自定义RequestMappingHandlerMapping的票据:https://jira.springsource.org/browse/SPR-11253。如果你感兴趣,请投票。

在重写时,也要注意考虑自定义执行管理重写。否则,所有自定义Exception映射都将失败。你必须使用列表bean重用messageCoverters:

<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中实现了一组关于这些主题的测试:参见https://github.com/resthub/resthub-spring-stack/pull/219/files和https://github.com/resthub/resthub-spring-stack/issues/217

据我所知,这个问题只出现在请求映射结束时的路径变量。

我们可以通过在requestmapping中定义regex插件来解决这个问题。

 /somepath/{variable:.+}

如果您正在使用Spring 3.2+,那么下面的解决方案将有所帮助。这将处理所有的url,所以肯定比在请求URI映射中应用regex模式更好。喜欢/ somepath /{变量:。+}

在xml文件中定义一个bean

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
        <property name="useSuffixPatternMatch" value="false"/>
        <property name="useRegisteredSuffixPatternMatch" value="true"/>
    </bean>

标志的用法可以在文档中找到。我把剪报解释一下

解释useRegisteredSuffixPatternMatch据说可以解决这个问题。来自类中的java文档

If enabled, a controller method mapped to "/users" also matches to "/users.json" assuming ".json" is a file extension registered with the provided {@link #setContentNegotiationManager(ContentNegotiationManager) contentNegotiationManager}. This can be useful for allowing only specific URL extensions to be used as well as in cases where a "." in the URL path can lead to ambiguous interpretation of path variable content, (e.g. given "/users/{user}" and incoming URLs such as "/users/john.j.joe" and "/users/john.j.joe.json").