web-dev-qa-db-ja.com

Spring MVC-HttpMediaTypeNotAcceptableException

AJAX Spring MVCおよびJSONで使用する場合のリクエストに対して、このHttpMediaTypeNotAcceptableExceptionエラーが発生し続けます。エラーの完全なスタックトレースは..

 org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.writeWithMessageConverters(AnnotationMethodHandlerAdapter.Java:1032)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.handleResponseBody(AnnotationMethodHandlerAdapter.Java:972)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.getModelAndView(AnnotationMethodHandlerAdapter.Java:921)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.Java:438)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.Java:424)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.Java:863)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.Java:792)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.Java:851)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.Java:756)
javax.servlet.http.HttpServlet.service(HttpServlet.Java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.Java:717)

私がやった小さなグーグルは、リクエストが持っている「accept:application/json」のようなものを含むべきであることを示しています。

Response Headers
Server  Apache-Coyote/1.1
Content-Type    text/html;charset=utf-8
Content-Length  2503
Date    Thu, 25 Aug 2011 21:00:05 GMT
Connection  close

Request Headers
Host    localhost:8080
User-Agent  Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.20) Gecko/20110803 Firefox/3.6.20 (.NET CLR 3.5.30729)
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
Keep-Alive  115
Connection  keep-alive
X-Requested-With    XMLHttpRequest
Referer http://localhost:8080/legaldirectory/index.html
Cookie  JSESSIONID=5C97DA19AED4D5FA17F4A58470FAA93B

今、私はここで何が起こっているのか完全に失われています。

43
RKodakandla

Spring xmlファイルに次のものがあることを確認してください。

<context:annotation-config/> 

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

また、POJOのすべてのアイテムにはゲッター/セッターが必要です。それが役に立てば幸い

48
danny.lesnik

From: http://georgovassilis.blogspot.ca/2015/10/spring-mvc-rest-controller-says-406.html

これはSpring@ RestControllerであり、URLパスの一部として電子メールを含むURLをマップしました。ドット切り捨ての問題を巧妙に回避し[1]、ロールする準備ができました。そして突然、一部のURLでSpringは406 [2]を返します。これは、ブラウザーが特定のコンテンツタイプを要求し、Springはそのコンテンツへの応答をシリアル化できないことを示しますタイプ。ポイントは、あなたが長年Spring申請をしていて、すべてのMVC宣言を正しく行い、ジャクソンを含めて、基本的に行き詰まっているということです。さらに悪いことに、URLパスの一部の電子メール、特に「.com」ドメインで終わる電子メールでのみエラーが発生します。

@RequestMapping(value = "/agenda/{email:.+}", method = RequestMethod.GET)
public List<AgendaEntryDTO> checkAgenda(@PathVariable("email") String email)

問題[3]は非常にトリッキーです。アプリケーションサーバーはコンテンツネゴシエーションを実行し、ブラウザが "application/x-msdownload"コンテンツを要求したことをSpringに納得させます。それにもかかわらず、ブラウザが実際に送信したリクエストのどこにも発生しません。

解決策は、Webアプリケーションコンテキストのコンテンツネゴシエーションマネージャーを指定することです。

<mvc:annotation-driven enable-matrix-variables="true"
    content-negotiation-manager="contentNegotiationManager" />
<bean id="contentNegotiationManager"
    class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
    <property name="defaultContentType" value="application/json" />
    <property name="favorPathExtension" value="false" />
    <property name="favorParameter" value="false" />
    <property name="parameterName" value="mediaType" />
    <property name="ignoreAcceptHeader" value="false" />
    <property name="useJaf" value="false" />
</bean>
22
Alex

両方のJackson jarをクラスパスに追加してください:

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

また、Spring xmlファイルには次のものが必要です。

<mvc:annotation-driven />
19
jokas

心に留めておくべき重要なこと:3.1.2より前のSpringバージョンはJACKSON 1.xと互換性があり、JACKSON 2.xとは互換性がありません。これは、JACKSON 1.xから2.xに移行すると、クラスのパッケージ名が変更されたためです。 JACKSON 1.xではクラスはorg.codehaus.jacksonの下にあり、JACKSON 2.xではクラスはcom.fasterxml.jacksonの下にあります。

この問題に対処するため、Spring 3.1.2以降では、MappingJacksonHttpMessageConverterに代わる新しいMappingJackson2HttpMessageConverterを追加しました。

このリンクで互換性の問題に関する詳細を見つけることができます: JacksonアノテーションはSpringでは無視されます

10
Erikson

これは「HttpMediaTypeNotAcceptableException」の最初のグーグルヒットであるため、つまずき、HttpMediaTypeNotAcceptableExceptionも発生させた別の問題を追加したいと思います。

私の場合、それは「プロデュース」を指定したコントローラーでした。例えば:

@RequestMapping(path = "/mypath/{filename}", method = RequestMethod.GET,
        produces = { MediaType.APPLICATION_XML_VALUE }

xMLファイルを提供したかったからです。同時に、「@ ControllerAdvice」を持つクラスを使用して例外をキャッチしています。要求されたファイルが見つからなかった場合。例外ハンドラーはJSONを返していたため、クライアント(角度付き)アプリはSPAのどこかにエラーメッセージを表示できました。

これで、コントローラーはXMLを返したいが、例外ハンドラーがJSONを返していたため、HttpMediaTypeNotAcceptableExceptionが発生しました。 JSONを可能な「プロデュース」値として追加することでこれを解決しました。

produces = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE}

これが他の誰かに役立つことを願っています。 :-)

10
andreas

私の場合favorPathExtension(false)助けて

@Configuration
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {

@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
    configurer
            .setUseSuffixPatternMatch(false);  // to use special character in path variables, for example, `[email protected]`
}

@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    configurer
            .favorPathExtension(false); // to  avoid HttpMediaTypeNotAcceptableException on standalone Tomcat
}

}

6
panser

Springで@ Configurationを拡張するクラスWebMvcConfigurerAdapterメソッドconfigureMessageConvertersをオーバーライドします。たとえば:

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {

    // http
    HttpMessageConverter converter = new StringHttpMessageConverter();
    converters.add(converter);
    logger.info("HttpMessageConverter added");

    // string
    converter = new FormHttpMessageConverter();
    converters.add(converter);
    logger.info("FormHttpMessageConverter added");

    // json
    converter = new MappingJackson2HttpMessageConverter();
    converters.add(converter);
    logger.info("MappingJackson2HttpMessageConverter added");

}

そして、エラーはなくなります。

4
zygimantus

私は同じ問題を抱えていましたが、基本的には、春が応答をレンダリングしようとすると、指定したメディアタイプに応じて、クラスでゲッターメソッドとセッターメソッドを使用してそれをシリアル化しようとすることがわかりました

私のクラスが以下のようになる前

public class MyRestResponse{
    private String message;
}

解決策は以下のようになります

public class MyRestResponse{
    private String message;
    public void setMessage(String msg){
        this.message = msg;
    }
    public String getMessage(){
        return this.message;
    }
}

それは私のために働いた方法です

2
mekbib.awoke

「jackson-databind」jarをpom.xmlに追加してみてください

`<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>${jackson.databind-version}</version>
</dependency>`

そして、produces ={MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE}から@RequestMapping

エス@RequestMapping(value = "/api/xxx/{akey}/{md5}", produces ={MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE}@RequestMapping(value = "/api/contrassegno/{akey}/{md5}", produces ={MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE},...

1
Mauro DiBi

答えよりもコメントの方が...

私はLombokを使用しており、(非常に)スケルトンAPIを開発しており、応答DTOには(まだ)フィールドがなく、統合テストの実行中にHttpMediaTypeNotAcceptableExceptionエラーが発生しました。

応答DTOにフィールドを追加すると、問題が修正されました。

0
jeremyt

私の場合

 {"timestamp":1537542856089,"status":406,"error":"Not Acceptable","exception":"org.springframework.web.HttpMediaTypeNotAcceptableException","message":"Could not find acceptable representation","path":"/a/101.xml"}

原因は:

path = "/path/{VariableName}"しかし、 "abc.xml"のようなサフィックス付きのVariableNameを渡していました。これにより、.xmlを フォーマットリクエスト のようなものとして解釈します。回答をご覧ください。

0
rogerdpack

Alex 回答の1つで示唆されているように、ContentNegotiationManagerFactoryBeanを使用してデフォルトのコンテンツタイプを「application/json」に設定できますが、そのアプローチは私には向かないと感じました。

私がやろうとしていたのは、このようなメソッドにフォームを投稿することでした

@RequestMapping(value = "/post/to/me", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public @ResponseBody MyJsonPOJO handlePostForm(@Valid @ModelAttribute("form") ValidateMeForm form, BindingResult bindingResult) throws ApiException {

私が代わりに選んだのは、ブラウザからのリクエストの「Accept」ヘッダーを「application/json」に変更し、SpringMVCに私のメソッドを見つけさせることでした。

(まだ完成していない)Javascript Fetch APIを使用する:

var form = new FormData();
form.append("myData", "data");

let fetchConfig = {
    method: "POST",
    body: form,
    headers: {"Accept": "application/json"}
};

fetch("/post/to/me", fetchConfig)
    .then(... // Javascript Promise API here

ほら!これで、SpringMVCはメソッドを見つけてフォームを検証し、JSON POJOを返すことができます。

0
Erik Zivkovic

私の場合、この問題を解決するには、@ResponseBody注釈を追加するだけです。

0
nguyentaijs

私にとって問題は、アクセスしようとしたURLでした。私はこのようなURLを持っていました:

{{ip}}:{{port}}/{{path}}/person.html

Urlを.htmlで終了すると、html以外のペイロードを受け入れないことを意味します。エンドポイントが正しく機能するためには、末尾から.htmlを削除する必要がありました。 (URLの最後に.jsonを追加することもできます。これも機能します)

さらに、web.xmlのurl-patternを適切に構成して、リソースにアクセスできるようにする必要があります。私にとっては

<servlet-mapping>
        <servlet-name>spring-mvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

以前は*.html*があり、エンドポイントへのアクセスを妨げていました。

0
Shoter