406を取得するSpringJSONリクエスト(受け入れられません)


85

これは私のJavaScriptです:

    function getWeather() {
        $.getJSON('getTemperature/' + $('.data option:selected').val(), null, function(data) {
            alert('Success');                               
        });
    }

これは私のコントローラーです:

@RequestMapping(value="/getTemperature/{id}", headers="Accept=*/*", method = RequestMethod.GET)
@ResponseBody
public Weather getTemparature(@PathVariable("id") Integer id){
    Weather weather = weatherService.getCurrentWeather(id);
        return weather;
}

spring-servlet.xml

<context:annotation-config />
<tx:annotation-driven />

このエラーの取得:

GET http://localhost:8080/web/getTemperature/2 406 (Not Acceptable)

ヘッダー:

応答ヘッダー

Server  Apache-Coyote/1.1
Content-Type    text/html;charset=utf-8
Content-Length  1070
Date    Sun, 18 Sep 2011 17:00:35 GMT

リクエストヘッダー

Host    localhost:8080
User-Agent  Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0.2) Gecko/20100101 Firefox/6.0.2
Accept  application/json, text/javascript, */*; q=0.01
Accept-Language en-us,en;q=0.5
Accept-Encoding gzip, deflate
Accept-Charset  ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection  keep-alive
X-Requested-With    XMLHttpRequest
Referer http://localhost:8080/web/weather
Cookie  JSESSIONID=7D27FAC18050ED84B58DAFB0A51CB7E4

興味深いメモ:

406エラーが発生しますが、その間、休止状態のクエリは機能します。 これは、Dropboxで選択を変更するたびに、Tomcatログが言うことです。

 select weather0_.ID as ID0_0_, weather0_.CITY_ID as CITY2_0_0_, weather0_.DATE as DATE0_0_, weather0_.TEMP as TEMP0_0_ from WEATHER weather0_ where weather0_.ID=?

問題は何でしょうか?以前、SOには2つの同様の質問がありました。そこで受け入れられたすべてのヒントを試しましたが、うまくいきませんでした...

助言がありますか?お気軽にご質問ください...

回答:


107

406受け入れられない

リクエストによって識別されたリソースは、リクエストで送信されたacceptヘッダーに従って受け入れられないコンテンツ特性を持つ応答エンティティのみを生成できます。

したがって、リクエストのacceptヘッダーはapplication / jsonであり、コントローラーはそれを返すことができません。これは、@ ResponseBodyアノテーション付きの戻り値を満たす正しいHTTPMessageConverterが見つからない場合に発生します。HTTPMessageConverterは<mvc:annotation-driven>、クラスパスに特定の3Dパーティライブラリを指定すると、を使用すると自動的に登録されます。

クラスパスに正しいJacksonライブラリがないか、<mvc:annotation-driven>ディレクティブを使用していません 。

私はあなたのシナリオをうまく複製しました、そしてそれはこれらの2つのライブラリを使用してそしてheaders="Accept=*/*"ディレクティブなしでうまく働きました。

  • jackson-core-asl-1.7.4.jar
  • jackson-mapper-asl-1.7.4.jar

いいえ、それは問題ではありませんでした、私の答えを確認してください。
Jaanus 2011

HttpMessageConvertersを手動で構成することで問題が解決した場合、mvc:annotation-drivenを使用すると、コンバーターとHandlerAdapters(HA)を自動的に構成するのと同じようになります。HAを明示的に構成すると、他のすべてのデフォルトがキャンセルされることに注意してください。
Villu Sepman 2011

うーん、それは何mvcですか?私が使用し<tx:annotation-driven />、txはxmlns:tx="http://www.springframework.org/schema/tx"
Jaanus 2011

1
次のようなものがあります: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">およびspring-web-3.0.xおよびspring-webmvc-3.0.x jar?
Villu Sepman 2011

1
ああ、私はそこにそのスキーマロケーションを持っていませんでした..しかし、ありがとう、これは私を助けました。それtx:annotation-drivenmvc:annotation-drivesmthinと同じかsmthinだと思いました。
Jaanus 2011

74

同じ問題が発生しました。最新のSpring4.1.1以降では、pom.xmlに次のjarを追加する必要があります。

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.4.1</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.4.1.1</version>
</dependency>

また、次のjarファイルがあることを確認してください。

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-core-asl</artifactId>
    <version>1.9.13</version>
</dependency>

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.9.13</version>
</dependency>

406 Spring MVC Json、リクエストの「accept」ヘッダーによると受け入れられません


この回答は、トップ回答のMaven対応バージョンであり、完全に機能します。Mavenの例外は、内部で実際に何が起こっているかについてより明確になる可能性があります。
コッタ2015年

4
これがSpringsの公式ドキュメントのどこに記載されているかを教えてください。これが問題であることを誰かがどうやって知ることができますか?
アデリン2015

jackson-databindとjackson-mapper-aslへの依存関係を指定するだけでよく、他の2つは推移的な依存関係であり、とにかく解決されます。
2015

1
これは、次の2つの依存関係を追加した後でのみ機能しました。ありがとう。
docWatson 2015年

あなたは間違いなく両方を必要としません。SpringはJackson1MappingJacksonHttpMessageConverterとJackson2に追加MappingJackson2HttpMessageConverterされます。これらはそれぞれJSONをシリアル化/逆シリアル化するのに十分です。必要なのは1つだけです(機能が豊富なため、Jackson 2を使用してください)。
Sotirios Delimanolis 2015年

16

このステータスが返される別のケースがあります。JacksonマッパーがBeanをシリアル化する方法を理解できない場合です。たとえば、同じブールプロパティに対して2つのアクセサメソッドがある場合、isFoo()およびgetFoo()

何が起こっているのかというと、SpringのMappingJackson2HttpMessageConverterがJacksonのStdSerializerProviderを呼び出して、オブジェクトを変換できるかどうかを確認します。コールチェーンの最下部で、有益なメッセージとともにをStdSerializerProvider._createAndCacheUntypedSerializerスローしJsonMappingExceptionます。ただし、この例外はに飲み込まれStdSerializerProvider._createAndCacheUntypedSerializer、オブジェクトを変換できないことをSpringに通知します。コンバーターが不足しているため、Springは、Accept使用できるヘッダーが与えられていないことを報告しています。もちろん、それを与えると偽物になります*/*

この動作にはバグがありますが、「再現できません」としてクローズされました。呼び出されているメソッドはスローできることを宣言していないため、例外を飲み込むことは明らかに適切な解決策です(そう、それは皮肉でした)。残念ながら、Jacksonにはロギングがありません...そしてコードベースにはそれを望んでいるコメントがたくさんあるので、これだけが隠された落とし穴ではないと思います。


どうもありがとうございます!私はSpringMVCを初めて使用し、JSONを返す方法を理解するのに非常に苦労していました。406エラーの原因として、@ ResponseBodyアノテーションとJackson依存関係の欠落について誰もが言及しています。私の場合、JSONとして返したいオブジェクトに属するパブリックフィールドのアクセサーメソッドが不足していることがわかりました。
アンソニージャック

ありがとう@kdgregory!フィールドにゲッター/セッターを追加するのを忘れました。それらを追加すると、この問題が修正されました。
Rubens Mariuzzo 2015

16

同じ問題が発生しました。コントローラーメソッドは実行されますが、応答はエラー406です。デバッグするAbstractMessageConverterMethodProcessor#writeWithMessageConvertersと、メソッドがContentNegotiationManager#resolveMediaTypes常に返さtext/htmlれることがわかりましたMappingJacksonHttpMessageConverter。これはでサポートされていません。問題は、 org.springframework.web.accept.ServletPathExtensionContentNegotiationStrategyより早く動作することでorg.springframework.web.accept.HeaderContentNegotiationStrategyあり、リクエストの拡張が/get-clients.htmlエラー406の問題の原因です/get-clients。リクエストのURLをに変更しました。


こんにちはアトット、私は同じ問題を抱えており、リクエストの拡張子を変更することについてのあなたのヒントは私の問題を解決しました。ソリューションを共有していただきありがとうございます!!
jherranzm 2014年

私の場合、同じ理由で406を引き起こしたのは(テストで)拡張子が付いたRESTパスIDでしたが、通常のコントローラーは機能します(RESTパスIDで拡張子を使用した場合でも)。
Jur_

9

次の2jarがクラスパスに存在することを確認してください。

いずれかまたは両方が欠落している場合、このエラーが発生します。

jackson-core-asl-1.9.X.jar jackson-mapper-asl-1.9.X.jar

6

ここから最終的に答えが見つかりました:

安らかなajaxリクエストを春にマッピングする

私は引用します:

@ RequestBody / @ ResponseBodyアノテーションは、通常のビューリゾルバーを使用せず、独自のHttpMessageConvertersを使用します。これらのアノテーションを使用するには、リファレンスで説明されているように、AnnotationMethodHandlerAdapterでこれらのコンバーターを構成する必要があります(おそらくMappingJacksonHttpMessageConverterが必要です)。


3

<mvc:annotation-driven />追加しない場合は、dispatcherservlet.xmlをチェックインします。そして追加

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-core-asl</artifactId>
    <version>1.9.13</version>
</dependency>

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.9.13</version>
</dependency>

pom.xmlのこれらの依存関係


2
<dependency>
    <groupId>com.fasterxml.jackson.jaxrs</groupId>
    <artifactId>jackson-jaxrs-base</artifactId>
    <version>2.6.3</version>
</dependency>

2
このコードは質問に答えることができますが、問題を解決する方法理由に関する追加のコンテキストを提供すると、回答の長期的な価値が向上します。
Francesco Menzani 2015年

2

おそらく誰もここまでスクロールダウンしていませんが、上記の解決策のいずれも私のためにそれを修正しませんでしたが、私のすべてのゲッターメソッドを作成publicしました。

私はゲッターの可視性をpackage-privateに残しました。ジャクソンはそれらを見つけることができないと判断し、爆破した。(@JsonAutoDetect(getterVisibility=NON_PRIVATE)部分的にのみ使用して修正しました。


それはまさに私の問題でした。セッターをパブリックからプロテクトに変更すると、ジャクソンは動作を停止しました。
JuanMiguel

ここでも同じ問題があります。キーのセッターがないAbstractMap.SimpleImmutableEntryためAbstractMap.SimpleEntry、使用してからダウングレードしましたが、まだダイスはありません。これでpojoはなくなりました。
ロバートベイン

2

送信されたオブジェクト(この場合は天気)にgetter / setterが含まれていることを確認してください


1

コントローラでは、次のように、応答本文のアノテーションをメソッドではなく戻り値の型に含めるべきではありません。

@RequestMapping(value="/getTemperature/{id}", headers="Accept=*/*", method = RequestMethod.GET)
public @ResponseBody Weather getTemparature(@PathVariable("id") Integer id){
    Weather weather = weatherService.getCurrentWeather(id);
        return weather;
}

また、生のjquery.ajax関数を使用して、contentTypeとdataTypeが正しく設定されていることを確認します。

別の言い方をすれば、jsonの春の処理にはかなり問題があると思います。文字列とGSONを使ってすべて自分でやったほうが簡単でした。


の配置は@ResponseBody重要ではありません... GSONを調べます...しかし、可能であれば、このJSONが機能することを望んでいます。
Jaanus 2011

1

@atottが述べたように

最新バージョンのJacksonをpom.xmlに追加し、Spring 4.0以降で、@ResponseBodyアクションメソッドを@RequestMapping使用して構成したproduces="application/json;charset=utf-8"場合でも、406(受け入れられない)が発生するので、これを試してみる必要があると思います。 MVC DispatcherServletコンテキスト構成:

<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" />

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

それが私の問題を最終的に解決した方法です。


1

Spring 4.3.10:以下の設定を使用して問題を解決しました。

ステップ1:以下の依存関係を追加します

    <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.6.7</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.6.7</version>
</dependency>
<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-core-asl</artifactId>
    <version>1.9.13</version>
</dependency>
<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.9.13</version>
</dependency>

ステップ2:MVCDispatcherServletコンテキスト構成に以下を追加します。

<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager"/>

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

Spring 3.2以降、デフォルト設定に従って、favorPathExtensionはtrueに設定されています。これにより、リクエストURIにSpringのような適切な拡張機能がある場合、拡張機能.htmが優先されます。ステップ2で、これをオーバーライドするためにcontentNegotiationManagerBeanを追加しました。


1

@EnableWebMvcアノテーションが欠落していたため、同じ問題が発生していました。(私のSpring構成はすべてアノテーションベースであり、同等のXMLはmvc:annotation-drivenになります)


0

クラスパスに正しいジャクソンバージョンがあることを確認してください


jackson-all-1.8.5.jarをWEB-INF/libフォルダーに追加しましたが、それでも同じ問題が発生します:/
Jaanus 2011

0

@joyfunがジャクソンの正しいバージョンを確認したように確認しますが、ヘッダーも確認します...クライアントによって送信されない/受け入れる可能性があります... firebugまたは同等のものを使用してgetリクエストが実際に送信しているものを確認します。100%確信はありませんが、アノテーション/ may /のheaders属性はリテラルをチェックしていると思います。


firebugのヘッダーをメインの投稿に追加しました。彼らは大丈夫ですか?
Jaanus 2011

0

それ以外に、Springサーブレットにすべての可能なJAR、依存関係、および注釈を含めても修正できない別の問題がありました。最終的に、ファイル拡張子が間違っていることがわかりました。つまり、同じコンテナで2つの別々のサーブレットを実行していて、一方が「.do」で、サブスクリプションに使用されるもう一方がランダムに「」という名前の異なるファイル拡張子にマップする必要がありました。サブ"。SUB以外はすべて、映画の字幕ファイルに通常使用される有効なファイル拡張子であるため、Tomcatはヘッダーをオーバーライドし、「text / x-dvd.sub ...」のようなものを返していました。すべて問題ありませんでしたが、アプリケーションはJSONを期待していましたが、字幕を取得していました。したがって、私がしなければならなかったのは、web.xml追加したファイルのマッピングを変更することだけです。

<mime-mapping>
    <extension>sub</extension>
    <mime-type>application/json</mime-type>
</mime-mapping>

0

私の問題は別のクラスのものだったので、残念ながらここでの解決策のどれも私の問題を解決しませんでした。

最初に、@ bekurによって提案されたようにすべての依存関係が設定されていることを確認し、次にクライアントからサーバーに移動する要求/応答がすべてのヘッダーがJqueryによって適切に設定されていることを確認しました。それから私RequestMappingHandlerAdapter MessageConvertersはそれらの7つすべてが整っていることを確認しました、私は本当に春を嫌い始めました!その後、Spring4.0.6.RELEASEから4.2.0.RELEASEに更新しましたが、上記ではなく別の応答があります。そうだったRequest processing failed; nested exception is java.lang.IllegalArgumentException: No converter found for return value of type

これが私のコントローラーメソッドです

  @RequestMapping(value = "/upload", method = RequestMethod.POST,produces = "application/json")
    public ResponseEntity<UploadPictureResult> pictureUpload(FirewalledRequest initialRequest) {

        DefaultMultipartHttpServletRequest request = (DefaultMultipartHttpServletRequest) initialRequest.getRequest();

        try {
            Iterator<String> iterator = request.getFileNames();

            while (iterator.hasNext()) {
                MultipartFile file = request.getFile(iterator.next());
                session.save(toImage(file));
            }
        } catch (Exception e) {
            return new ResponseEntity<UploadPictureResult>(new UploadPictureResult(),HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return new ResponseEntity<UploadPictureResult>(new UploadPictureResult(), HttpStatus.OK);
    } 




    public class UploadPictureResult extends WebResponse{

    private List<Image> images;

    public void setImages(List<Image> images) {
        this.images = images;
    }
}






    public class WebResponse implements Serializable {


    protected String message;

    public WebResponse() {
    }

    public WebResponse(String message) {

        this.message = message;
    }


    public void setMessage(String message) {
        this.message = message;
    }
}

解決策は、UploadPictureResultがWebResponseを拡張しないようにすることでした

何らかの理由で、SpringはWebResponseを拡張したときにUploadPictureResltを変換する方法を決定できませんでした


0
<dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.8.0</version>
    </dependency>

私はSSL認証を使用せず、このjackson-databindにはjackson-core.jarとjackson-databind.jarが含まれており、RequestMappingの内容を次のように変更します。

@RequestMapping(value = "/id/{number}", produces = "application/json; charset=UTF-8", method = RequestMethod.GET)
public @ResponseBody Customer findCustomer(@PathVariable int number){
    Customer result = customerService.findById(number);
    return result;
}

注意: プロデュースが「application / json」タイプではなく、これに気づかずに406エラーが発生した場合は、これが役立つ可能性があります。


0

このスレッドを確認してください。 spring mvc restcontroller return json string p / s:WebMvcConfigクラスにjacksonマッピング構成を追加する必要があります

@Override protected void configureMessageConverters( List<HttpMessageConverter<?>> converters) { // put the jackson converter to the front of the list so that application/json content-type strings will be treated as JSON converters.add(new MappingJackson2HttpMessageConverter()); // and probably needs a string converter too for text/plain content-type strings to be properly handled converters.add(new StringHttpMessageConverter()); }


0

これは、springVersion = 5.0.3.RELEASEの更新の回答です。

上記の回答は、古いspringVersion <4.1バージョンでのみ機能します。最新の春には、gradleファイルに次の依存関係を追加する必要があります。

compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: fasterxmljackson
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: fasterxmljackson

fasterxmljackson=2.9.4

これが最新のSpringバージョンを使用している人に役立つことを願っています。


-3

@RequestMappingのheaders要素を削除して試してみてください。

お気に入り


@RequestMapping(value="/getTemperature/{id}", method = RequestMethod.GET)

Springは、acceptヘッダーに完全に一致するのではなく、「containscheck」を実行すると思います。しかし、それでも、headers要素を削除して確認する価値はあります。


削除しましたが、それでもエラーが発生します。ところで、Tomcatログを見ると、これを使用したクエリがweatherService.getCurrentWeather(id);「アクティブ化」されました...何かが機能します... 406が表示され、Hibernate SQL selectが同時に機能する可能性はありますか?
Jaanus 2011

これでうまくいくはずです。このアノテーションをコントローラーに追加します@RequestMapping(method = RequestMethod.GET、headers = {"Accept = text / xml、application / json"})
2016年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.