9

SpringMVCアプリケーションをSpring3.2にアップグレードした後、一部のURLにアクセスすると次の例外が発生します。

org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
    at org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.handleNoMatch(RequestMappingInfoHandlerMapping.java:203) ~[spring-webmvc-3.2.0.RELEASE.jar:3.2.0.RELEASE]
    at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lookupHandlerMethod(AbstractHandlerMethodMapping.java:272) ~[spring-webmvc-3.2.0.RELEASE.jar:3.2.0.RELEASE]
    at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:212) ~[spring-webmvc-3.2.0.RELEASE.jar:3.2.0.RELEASE]
    at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:55) ~[spring-webmvc-3.2.0.RELEASE.jar:3.2.0.RELEASE]
    at org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:297) ~[spring-webmvc-3.2.0.RELEASE.jar:3.2.0.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1091) ~[spring-webmvc-3.2.0.RELEASE.jar:3.2.0.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1076) ~[spring-webmvc-3.2.0.RELEASE.jar:3.2.0.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:896) ~[spring-webmvc-3.2.0.RELEASE.jar:3.2.0.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856) ~[spring-webmvc-3.2.0.RELEASE.jar:3.2.0.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:915) [spring-webmvc-3.2.0.RELEASE.jar:3.2.0.RELEASE]
(...)

この例外により、HTTP406が受け入れられなくなります。

アクセスできないURLを使用して簡略化されたコントローラーを作成できました。

@RequestMapping(value = "/resources/foo.js", produces = "text/javascript")
@ResponseBody
public String foo() throws Exception {
    return "";
}

*/*-headerにある通常のブラウザを使用しているAcceptので、HTTP 406を取得する必要がある理由がわかりません。これをさらに奇妙なものにしているのは、このコードがSpring 3.1.2で動作しているが、Springでは動作していないことです。 3.2。何故ですか?

4

4 に答える 4

10

Springが3.2でコンテンツネゴシエーションを行う方法に関連するいくつかの変更がありました。これらの変更の1つは、URLのファイルサフィックスに基づいてコンテンツネゴシエーションを実行できるようになったことです。この機能はデフォルトで有効になっています。3.2より前のSpringバージョンでは、HTTPaccept-headerがコンテンツネゴシエーションに使用されていました。ブラウザがURLにアクセスしたとき、ブラウザは常にを送信するため、コンテンツネゴシエーションが問題になることはめったにありませんでしたAccept:(...)*/*

Springにはサフィックス=>メディアタイプのマップがあります。「.js」の場合、デフォルトのメディアタイプは「application/x-javascript」です。Springが/resources/foo.jsへのリクエストのハンドラーマッピングを検索しようとするとfoo()、間違ったメディアタイプが生成されるため、-methodと一致しません。

春のチームがこの事件を考え抜いたかどうかはわかりません。@RequestMappingアクセスできないを作成できるのは少なくとも少し奇妙です(.js-mediaタイプとproducesフィールドに設定されているものとの非互換性のため)。

この問題を修正するには、いくつかの方法があります。1つは、produces-parameterを「application/x-javascript」に変更することです。もう1つは、「。js」のメディアタイプを「text / javascript」に変更することです(これを行う方法のドキュメントを参照してください)。3番目の可能性は、サフィックスに基づいてコンテンツネゴシエーションをオフにすることです(これも、その方法のドキュメントを参照してください)。

于 2012-12-15T21:17:26.350 に答える
2

要求されたパスの拡張に基づいてメディアタイプの取得を無効にすることで、これが機能するようになりました。これは、次の方法で実行できます。

    <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager"/>
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
    <!-- Turn off working out content type based on URL file extension, should fall back to looking at the Accept headers -->
    <property name="favorPathExtension" value="false" />
</bean>

そして、すべてのxsdスキーマの場所にバージョン3.2を指定します。

于 2013-07-02T08:13:30.210 に答える
0

MessageConverterジャクソンのためにすでに持っているかもしれないものと一緒に、あなたはあなたの構成に適切なものを追加する必要があります。

たとえば、次のサブクラスでWebMvcConfigurerAdapter

@Override
public void configureMessageConverters(final List<HttpMessageConverter<?>> converters) {
    converters.add(new StringHttpMessageConverter());
}

favorPathExtensionオプションをオンのままにしておくと、producesパラメーターも必要なくなり、コントローラーはを返しapplication/javascriptます。

Aleksandersの回答のヒントは、同じ問題が発生したときに406を取り除くのに実際には役立ちませんでした。

于 2014-09-16T14:31:02.210 に答える
0

コントローラへのREST呼び出しで、パス値に.auを含むパス変数が含まれているという同様の問題があります。Springは、Spring Content Negotiationにより、ファイル拡張子として.auを読み取っています。

パス変数に.auが含まれているため、REST GET呼び出しはhttp:// localhost:8080 / api / forgot-password/kk@kudeta.com.auです。Springはorg.springframework.web.HttpMediaTypeNotAcceptableExceptionをスローしています。

コンテンツベースのネゴシエーションをオフにすることで解決しました

@Configuration
public class ContentNegotiationConfig extends WebMvcConfigurerAdapter{
    @Override
    public void configureContentNegotiation(final 
     ContentNegotiationConfigurer configurer) {
        // Turn off suffix-based content negotiation
        configurer.favorPathExtension(false);
    }

}
于 2017-09-08T16:56:16.513 に答える