389

これは、 Spring MVC @PathVariable が切り捨てられるという質問の続きです

Spring フォーラムは、ContentNegotiationManager の一部として修正 (3.2 バージョン) したと述べています。以下のリンクを参照してください。
https://jira.springsource.org/browse/SPR-6164
https://jira.springsource.org/browse/SPR-7632

私のアプリケーションでは、.com を含む requestParameter が切り捨てられています。

この新機能の使い方を誰か説明してくれませんか? xmlでどのように構成できますか?

注:スプリング フォーラム - #1 ドット (.) を含む Spring MVC @PathVariable が切り捨てられる

4

18 に答える 18

506

私の知る限り、この問題はリクエストマッピングの最後にあるパス変数に対してのみ発生します。

requestmapping で正規表現アドオンを定義することで、これを解決できました。

 /somepath/{variable:.+}
于 2013-05-02T08:04:29.033 に答える
251

Spring は、最後のドットの後ろにあるものを.jsonorなどのファイル拡張子.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

マッピングを/somepath/{variable:.+}提案どおりに変更すると、最後のドットを含むすべてのドットがパラメータの一部と見なされます。

  • /somepath/param値を持つパラメータになりますparam
  • /somepath/param.json値を持つパラメータになりますparam.json
  • /somepath/param.xml値を持つパラメータになりますparam.xml
  • /somepath/param.anything値を持つパラメータになりますparam.anything
  • /somepath/param.value.json値を持つパラメータになりますparam.value.json
  • ...

拡張子の認識が気にならない場合は、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

注: デフォルトの構成との違いは、次のようなマッピングがある場合にのみ表示されます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 は、カスタム Bean を提供する contentNegotiation オプションを受け入れるようになりましたが、RequestMappingHandlerMapping のプロパティを true (デフォルトは false) に変更する必要があることに注意してください ( https://jira.springsource.org/browse/SPR-7632を参照)。 )。

そのため、すべての mvc:annotation 主導の構成をオーバーライドする必要があります。Spring へのチケットを開いて、カスタム RequestMappingHandlerMapping を要求しました: 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>

私が参加しているオープン ソース プロジェクトResthubでこれらのテーマに関する一連のテストを実装しましたgithub.com/resthub/resthub-spring-stack/issues/217

于 2013-12-23T12:48:06.620 に答える
97

PathMatchConfigurerSpring 4 の更新: 4.0.1 以降、 (を介して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>
于 2014-05-29T17:03:01.120 に答える
88

Martin Frey の回答に加えて、これは RequestMapping 値に末尾のスラッシュを追加することでも修正できます。

/path/{variable}/

この修正は保守性をサポートしないことに注意してください。現在、すべての URI に末尾のスラッシュが必要です。これは、API ユーザーや新しい開発者には明らかではない可能性があります。すべてのパラメータに が含ま.れているとは限らないため、断続的なバグが発生する可能性もあります

于 2013-08-22T11:11:50.993 に答える
12

この問題を回避する非常に簡単な方法の 1 つは、末尾にスラッシュを追加することです ...

例えば:

使用する :

/somepath/filename.jpg/

それ以外の:

/somepath/filename.jpg
于 2015-10-07T17:50:04.057 に答える
11

Spring Bootでは、正規表現は次のような問題を解決します

@GetMapping("/path/{param1:.+}")
于 2017-09-05T13:57:12.943 に答える
5

Spring 3.2.x および を使用している場合は<mvc:annotation-driven />、次の小さな を作成します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;
    }
}

次に、これを MVC 構成 xml に入れます。

<bean class="spring.DoNotTruncateMyUrls" />
于 2013-05-29T18:38:16.987 に答える
3

If you write both back and frontend, another simple solution is to attach a "/" at the end of the URL at front. If so, you don't need to change your backend...

somepath/myemail@gmail.com/

Be happy!

于 2020-10-27T18:52:55.033 に答える