52

簡単な JSON 応答を生成しようとしています。現在、406 Not Acceptable エラーが発生しています。Tomcat は、「このリクエストによって識別されたリソースは、リクエストの「受け入れ」ヘッダーに従って受け入れられない特性を持つ応答を生成することしかできない」と述べています。私のAcceptヘッダーは

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

tomcat/lib には、すべての Tomcat jar、Spring jar、および jackson-all-1.9.0.jar があります。Tomcat 7 で Spring 3.2.2 を使用しています。

この問題が何度も議論されていることは承知していますが、どの解決策もうまくいきません。

web.xml

<web-app id="WebApp_ID" version="2.4" 
    xmlns="http://java.sun.com/xml/ns/j2ee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

  <display-name>Spring Web MVC Application</display-name>

  <servlet>
    <servlet-name>dispatcher</servlet-name>
        <servlet-class>
                  org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
        <url-pattern>*.htm</url-pattern>
  </servlet-mapping>

</web-app>

dispatcher-servlet.xml

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
     http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
        <property name="prefix">
            <value>/WEB-INF/pages/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
    </bean>
 <context:component-scan base-package="com.smiechmateusz.controller" />
 <context:annotation-config />

    <mvc:annotation-driven />

</beans>

HelloWorldController.java

package com.smiechmateusz.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

import com.smiechmateusz.dao.Foo;

@Controller
@RequestMapping("/")
public class HelloWorldController extends AbstractController{

    @Override
    protected ModelAndView handleRequestInternal(HttpServletRequest request,
        HttpServletResponse response) throws Exception {

        ModelAndView model = new ModelAndView("HelloWorldPage");
        return model;
    }

    @RequestMapping(value="foobar.htm", method = RequestMethod.GET)
    public @ResponseBody Foo getShopInJSON() {
        Foo f = new Foo();
        f.setX(1);
        f.setY(2);
        f.setDescription("desc");
        return f;
    }
}

Foo.java

package com.smiechmateusz.dao;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="foobaz")
public class Foo implements Serializable
{
    private int x, y;
    String description;
    int id;

    @Column(name = "x")
    public int getX() {
        return x;
    }
    public void setX(int x) {
        this.x = x;
    }
    @Column(name = "y")
    public int getY() {
        return y;
    }
    public void setY(int y) {
        this.y = y;
    }
    @Column(name = "description")
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }

    @Id @GeneratedValue
    @Column(name = "id")
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
}

私はすでに追加しようとしました

<bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="messageConverters">
          <list>
            <ref bean="jsonConverter"/>
          </list>
    </property>
</bean>

私のdispatcher-servlet.xmlに変更するか、jakcson-alljackson- aslとjackson-core- aslに変更しましたが、出力は同じでした。

4

22 に答える 22

22

このエラーが発生するもう 1 つの方法は、パブリック メンバーを持たないクラスを作成することです。406 unacceptable は、このシナリオではまったく役に立たないエラー メッセージです。

于 2014-04-02T00:55:39.957 に答える
10

他の答えはどれも私を助けませんでした。

406 Not Acceptable、HttpMediaTypeNotAcceptableException、マルチパート ファイル、ResponseBody、Accept ヘッダーの設定、生成、消費などに関する多数の Stackoverflow の回答を読みました。

build.gradle で構成された SpringBoot と Jackson を備えた Spring 4.2.4 がありました。

compile "com.fasterxml.jackson.core:jackson-core:2.6.7"
compile "com.fasterxml.jackson.core:jackson-databind:2.6.7"

他のコントローラーではすべてのルートが正常に機能し、GET、POST、PUT、および DELETE を使用できました。次に、マルチパート ファイル アップロード機能の追加を開始し、新しいコントローラーを作成しました。GET ルートは正常に機能しますが、POST と DELETE は機能しませんでした。ここSOでどのようにさまざまなソリューションを試しても、406 Not Acceptableを取得し続けました。

そして最後に、私はこのSOの答えに出くわしました: Spring throwing HttpMediaTypeNotAcceptableException: Could not find Acceptable Expression due to dot in url path

Raniz の回答とすべてのコメントを読んでください。

それはすべて @RequestMapping 値に要約されます。

@RequestMapping(value = "/audio/{fileName:.+}", method = RequestMethod.POST, consumes="multipart/*")
public AudioFileDto insertAudio(@PathVariable String fileName, @RequestParam("audiofile") MultipartFile audiofile) {

    return audioService.insert(fileName, audiofile);
}

@RequestMapping(value = "/audio/{fileName:.+}", method = RequestMethod.DELETE)
public Boolean deleteAudio(@PathVariable String fileName) {

    return audioService.remove(fileName);
}

{fileName:.+}@RequestMapping 値の一部が原因で、このケースでは 406 Not Acceptable が発生しました。

Ranizの回答から追加したコードは次のとおりです。

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

編集 2016 年 8 月 29 日:

使用中に問題が発生しましたconfigurer.favorPathExtension(false): 静的な SVG 画像が読み込まれなくなりました。分析の結果、Spring が「image/svg+xml」ではなく「application/octet-stream」というコンテンツ タイプで SVG ファイルを UI に送り返し始めたことがわかりました。次のように、クエリ パラメータとして fileName を送信することで、これを解決しました。

@RequestMapping(value = "/audio", method = RequestMethod.DELETE)
public Boolean deleteAudio(@RequestParam String fileName) {

    return audioService.remove(fileName);
}

も削除しましたconfigurer.favorPathExtension(false)。別の方法として、パス内の fileName をエンコードすることもできますが、さらなる副作用を回避するために、クエリ パラメーター メソッドを選択しました。

于 2016-07-21T10:21:04.363 に答える
10

Spring 4 では、次のように追加するだけです@EnableWebMvc

@Controller
@EnableWebMvc
@RequestMapping(value = "/articles/action", headers="Accept=*/*",  produces="application/json")
public class ArticlesController {

}
于 2015-05-15T17:53:29.820 に答える
7

あなたのポンで以下の依存関係を使用してください

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.5.3</version>
</dependency>
于 2016-04-08T07:27:38.413 に答える
5

spring-mvc-config.xml に Jackson のアノテーション バインディングを登録する必要があります。次に例を示します。

<!-- activates annotation driven binding -->
<mvc:annotation-driven ignoreDefaultModelOnRedirect="true" validator="validator">
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.ResourceHttpMessageConverter"/>
        <bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"/>
        <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
    </mvc:message-converters>
</mvc:annotation-driven>

次に、コントローラーで次を使用できます。

@RequestMapping(value = "/your_url", method = RequestMethod.GET, produces = "application/json")
@ResponseBody
于 2013-05-02T12:57:30.863 に答える
1

おそらく、POJO のすべてのフィールドに Getter と Setter が必要です。

この問題に従って修正しました。参考:Spring MVC - HttpMediaTypeNotAcceptableException

また、406 はバグを修正するのに役立つメッセージではありません。コードをデバッグして、例外が何であるかを確認する必要があります。

于 2016-04-20T12:09:18.197 に答える
0

json 出力を生成/受信しようとしているようです。あなたのアプローチには2つの問題があります。1) Accept ヘッダーで application/json を指定していない 2) @RequestMapping でproduces="application/json" を指定する必要がある

于 2015-01-10T11:42:27.727 に答える
0

私の値は.htmlRequestMappingで終わっていましたが、これは何か違うはずです。

.jsonに変更してみましたが、うまくいきました。

于 2016-08-11T10:43:07.180 に答える
0

There is another case where this status will be returned: if the Jackson mapper cannot figure out how to serialize your bean. For example, if you have two accessor methods for the same boolean property, isFoo() and getFoo().

removed getFoo() and put isFoo(). it worked for me.

于 2015-01-28T06:58:10.793 に答える