4

私の Spring XML には、次のスニペットがあります。

<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
    <property name="useDefaultSuffixPattern" value="false"/>
</bean>

<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
            <property name="objectMapper" ref="objectMapper" />
        </bean>        
    </mvc:message-converters>
</mvc:annotation-driven>

私が理解していることから、これは、「abc」のマッピングがある場合、Spring が「abc.*」および「abc/」を登録してはならないことを意味します。

私のコントローラーの1つに、応答に画像を書き込むメソッドがあります。

@RequestMapping(value="{path}", method=RequestMethod.GET, produces=MediaType.IMAGE_PNG_VALUE)
@ResponseBody
public void getPath(
        @PathVariable String path,
        HttpServletResponse res) {

    ...
}

これは、「abc」などをリクエストするとうまく機能しますが、「abc.com」をリクエストすると、次のテキストで 406 エラーがスローされます。

The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers."

「abc.img」をリクエストすると、「path」パラメーターはテキスト「abc」のみを受け取ります。スプリングは拡張子を省略しています。

Spring が接尾辞パターンを正しく無視していないようです。どうしてこれなの?

編集: Dirk のコメントから Java 構成を翻訳しました。次の XML はこの問題を修正しているようです:

<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
    <property name="favorPathExtension" value="false" />
</bean>

<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager">
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
            <property name="objectMapper" ref="objectMapper" />
        </bean>        
    </mvc:message-converters>
</mvc:annotation-driven>

元のコードが機能しなかった理由はまだわかりませんが、これで問題は解決しました

4

1 に答える 1

14

Spring ディスパッチャーにリクエストが届くと、コントローラーのマッピング/マッチングの一部は、クライアント側で受け入れられたメディア タイプをコントローラー側で生成可能なメディア タイプに一致させます (そのため、生成されたメディア タイプによってのみ識別可能なコントローラーを使用できます)。 .

悪いニュースは、デフォルト構成の springmvc は、リクエスト内の受け入れヘッダーよりも、リクエストされた URLの拡張子を優先することです。

あなたの例でabcは、拡張機能に一致するものがないことを要求しているため、他のコンテンツのネゴシエーション戦略が最終的に正しいタイプに解決されます (acceptヘッダーを介して)。ただし、Spring を要求すると、コントローラーの と一致しないabc.comMIME タイプが派生し、が生成されます(一致するコントローラーがないため)。application/octet-streamproduces406

spring-context-support.jar のパス拡張子のデフォルトの MIME マッチングを見つけることができます( https://github.com/spring-projects/spring-framework/blob/master/spring-context-support/src/org/springframework/mail/javamail/mime.typesを参照)。 main/resources/org/springframework/mail/javamail/mime.types#L278 )。

ディスパッチャー設定でこの「機能」を無効にして、Spring がパス拡張子を使用して MIME タイプを解決しないようにすることができます。

<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
    <property name="favorPathExtension" value="false" />
</bean>

Java config を使用している場合は、関連する質問/回答をご覧ください。

于 2014-05-11T08:20:57.660 に答える