• Spring MVC @PathVariable被截断


    一、问题描述

      一个控制器提供RESTful访问信息:

    @RequestMapping(method = RequestMethod.GET, value = Routes.BLAH_GET + "/{blahName}")
    public ModelAndView getBlah(@PathVariable String blahName, HttpServletRequest request,
                                HttpServletResponse response) {
    

     遇到的问题是如果我用具有特殊字符的路径变量打到服务器,它将被截断。例如:http://localhost:8080/blah-server/blah/get/blah2010.08.19-02:25:47

     参数blahName将为blah2010.08,但是request.getRequestURI()的调用包含传入的所有信息。那么如何防止Spring截断@PathVariable?

    二、解决方案

      (A)最佳方案

       尝试@RequestMapping参数的正则表达式:

    RequestMapping(method = RequestMethod.GET, value = Routes.BLAH_GET + "/{blahName:.+}")
    

     (B)次佳解决方案

       这可能与SPR-6164密切相关。简而言之,框架尝试将一些智能应用于URI解释,删除它认为是文件扩展名。因为它认为.19-02:25:47是一个文件扩展名,所以这样会使blah2010.08.19-02:25:47变成blah2010.08。

      如链接问题中所述,您可以通过在应用程序上下文中声明自己的DefaultAnnotationHandlerMapping bean并将其useDefaultSuffixPattern属性设置为false来禁用此行为。这将覆盖默认行为,并阻止它骚扰您的数据。

    (C)第三种解决方案

     Spring认为最后一个点后面的任何东西都是一个文件扩展名,如.json或.xml,并截断它以检索你的参数。

     所以如果你有/{blahName}:

    • /param,/param.json,/param.xml或/param.anything将导致值为param的参数
    • /param.value.json,/param.value.xml或/param.value.anything将导致值为param.value的参数

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

    • /param将导致值为param的参数
    • /param.json将导致值为param.json的参数
    • /param.xml将导致值为param.xml的参数
    • /param.anything将导致值为param.anything的参数
    • /param.value.json将导致值为param.value.json的参数

    如果您不关心扩展识别,可以通过覆盖mvc:annotation-driven自动化来禁用它:

    <bean id="handlerMapping"
          class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
        <property name="contentNegotiationManager" ref="contentNegotiationManager"/>
        <property name="useSuffixPatternMatch" value="false"/>
    </bean>
    

     所以,再一次如果你有/{blahName}:

    • /param,/param.json,/param.xml或/param.anything将导致值为param的参数
    • /param.value.json,/param.value.xml或/param.value.anything将导致值为param.value的参数

    注意:与默认配置的区别只有在具有/something.{blahName}的映射时才可见。

    如果要保留扩展管理,因为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:annotation-driven配置。我向Spring打开了一张机票,要求一个CustomMappingHandlerMapping的定制:https://jira.springsource.org/browse/SPR-11253。如果您有兴趣,请投票。

     虽然重写,但请谨慎考虑自定义执行管理覆盖。否则,您的所有自定义异常映射将失败。您将不得不使用一个列表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>
    

     相关链接请参见:https://gxnotes.com/article/46793.html

  • 相关阅读:
    Delphi Help
    RAD 10 新控件 TSearchBox TSplitView
    滚动条
    c++builder Active Form
    chart左侧
    RAD 10 蓝牙
    浏览器插件 火狐插件
    c++builder delphi 调用dll dll编写
    模拟键盘 键盘虚拟代码
    oracle怎么把一个用户下的表复制给另一个用户?(授予表权限)
  • 原文地址:https://www.cnblogs.com/moonandstar08/p/7078263.html
Copyright © 2020-2023  润新知