json Spring MVC - HttpMediaTypeNotAcceptableException

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7197268/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 17:58:18  来源:igfitidea点击:

Spring MVC - HttpMediaTypeNotAcceptableException

jsonspringspring-mvcspring-json

提问by RKodakandla

I keep getting this HttpMediaTypeNotAcceptableException error for AJAX requests when using with Spring MVC and JSON.. full stack trace of the error is..

与 Spring MVC 和 JSON 一起使用时,我不断收到 AJAX 请求的 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)

little googling I did shows that the request should contain something like "accept: application/json" which is does have.. here is the request headers from firebug..

我做的小谷歌搜索表明请求应该包含类似“accept: application/json”的东西,它确实有..这是来自firebug的请求标头..

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

Now I am completely lost at what is happening here.. what else can go wrong here to get thi error...

现在我完全迷失在这里发生的事情......这里还有什么地方会出错以得到这个错误......

回答by danny.lesnik

Please make sure that you have the following in your Spring xml file:

请确保您的 Spring xml 文件中包含以下内容:

<context:annotation-config/> 

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

and all items of your POJO should have getters/setters. Hope it helps

并且你的 POJO 的所有项目都应该有 getter/setter。希望能帮助到你

回答by Alex

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

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

You've got this Spring@RestControllerand mapped a URL that contains an email as part of the URL path. You cunningly worked around the dot truncation issue [1] and you are ready to roll. And suddenly, on some URLs, Springwill return a 406 [2] which says that the browser requested a certain content type and Springcan't serialize the response to that content type. The point is, you've been doing Springapplications for years and you did all the MVC declarations right and you included Hymanson and basically you are stuck. Even worse, it will spit that error out only on some emails in the URL path, most notably those ending in a ".com" domain.

您已经获得了这个Spring @RestController并映射了一个包含电子邮件的 URL 作为 URL 路径的一部分。您巧妙地解决了点截断问题 [1],并准备好开始工作了。突然,在某些 URL 上,Spring将返回 406 [2],表示浏览器请求了某种内容类型,而Spring无法将响应序列化为该内容类型。关键是,你多年来一直在做Spring应用程序,你正确地做了所有 MVC 声明,你包括了 Hymanson,基本上你被卡住了。更糟糕的是,它只会在 URL 路径中的某些电子邮件上吐出该错误,最明显的是那些以“.com”域结尾的电子邮件。

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

The issue [3] is quite tricky: the application server performs some content negotiation and convinces Springthat the browser requested a "application/x-msdownload"content, despite that occurring nowhere in the request the browser actually submitted.

问题 [3] 非常棘手:应用程序服务器执行一些内容协商并让Spring相信浏览器请求了“application/x-msdownload”内容,尽管浏览器实际提交的请求中没有发生这种情况。

The solution is to specify a content negotiation manager for the web application context:

解决方案是为 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>

回答by jokas

Make sure you add both Hymanson jars to classpath:

确保将两个 Hymanson jar 添加到类路径:

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

Also, you must have the following in your Spring xml file:

此外,您的 Spring xml 文件中必须包含以下内容:

<mvc:annotation-driven />

回答by andreas

Because this is the first google hit for "HttpMediaTypeNotAcceptableException" I like to add another problem that I've stumbled upon which resulted in HttpMediaTypeNotAcceptableException too.

因为这是“HttpMediaTypeNotAcceptableException”的第一个谷歌命中,我想添加另一个我偶然发现的问题,它也导致了 HttpMediaTypeNotAcceptableException。

In my case it was a controller that specified "produces", e.g.:

就我而言,它是一个指定“生产”的控制器,例如:

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

because I wanted to serve an XML file. At the same time I'm using a class with "@ControllerAdvice" to catch Exceptions, e.g. if the requested file wasn't found. The Exception handler was returning JSON so the client (angular) app could display the error message somewhere in the SPA.

因为我想提供一个 XML 文件。同时,我使用带有“@ControllerAdvice”的类来捕获异常,例如,如果未找到请求的文件。异常处理程序返回 JSON,因此客户端(角度)应用程序可以在 SPA 中的某处显示错误消息。

Now the controller wanted to return XML but the Exception Handler was returning JSON so the HttpMediaTypeNotAcceptableException was raised. I solved this by adding JSON as possible "produces" value:

现在控制器想要返回 XML,但异常处理程序正在返回 JSON,因此引发了 HttpMediaTypeNotAcceptableException。我通过添加 JSON 作为可能的“产生”值来解决这个问题:

produces = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE}

Hope this helps somebody else. :-)

希望这对其他人有帮助。:-)

回答by Erikson

Just something important to keep in mind: Spring versions prior to 3.1.2 are compatible with HymanSON 1.x and NOT with HymanSON 2.x. This is because going from HymanSON 1.x to 2.x the classes's package names were changed. In HymanSON 1.x classes are under org.codehaus.Hymanson while in HymanSON 2.x they are under com.fasterxml.Hymanson.

需要记住的重要一点是:3.1.2 之前的 Spring 版本与 HymanSON 1.x 兼容,而不与 HymanSON 2.x 兼容。这是因为从 HymanSON 1.x 到 2.x,类的包名称发生了变化。在 HymanSON 1.x 中,类在 org.codehaus.Hymanson 下,而在 HymanSON 2.x 中,它们在 com.fasterxml.Hymanson 下。

To address this issue, starting with Spring 3.1.2 they added a new MappingHymanson2HttpMessageConverter to replace MappingHymansonHttpMessageConverter.

为了解决这个问题,从 Spring 3.1.2 开始,他们添加了一个新的 MappingHymanson2HttpMessageConverter 来替换 MappingHymansonHttpMessageConverter。

You could find more details regarding compatibility issues in this link: Hymanson annotations being ignored in Spring

您可以在此链接中找到有关兼容性问题的更多详细信息:Hymanson 注释在 Spring 中被忽略

回答by panser

in my case favorPathExtension(false)helped me

在我的情况下,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
}

}

}

回答by zygimantus

In your Spring @Configurationclass which extends WebMvcConfigurerAdapteroverride the method configureMessageConverters, for instance:

在扩展WebMvcConfigurerAdapter 的Spring @Configuration类中覆盖方法 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 MappingHymanson2HttpMessageConverter();
    converters.add(converter);
    logger.info("MappingHymanson2HttpMessageConverter added");

}

And the error will be gone.

错误将消失。

回答by mekbib.awoke

I had the same issue, but i had figured out that basically what happens when spring is trying to render the response it will try to serialize it according to the media type you have specified and by using getter and setter methods in your class

我遇到了同样的问题,但我发现基本上当 spring 试图呈现响应时会发生什么,它将尝试根据您指定的媒体类型并在您的类中使用 getter 和 setter 方法来序列化它

before my class used to look like below

在我的课以前看起来像下面这样

public class MyRestResponse{
    private String message;
}

solution looks like below

解决方案如下所示

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

that's how it worked for me

这就是它对我有用的方式

回答by Mauro DiBi

Try to add "Hymanson-databind" jars to pom.xml

尝试将“Hymanson-databind”罐子添加到 pom.xml

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

And produces ={MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE}to @RequestMapping

produces ={MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE}@RequestMapping

Es. @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},...

埃斯。 @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},...

回答by rogerdpack

In my case

就我而言

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

was caused by:

是由:

path = "/path/{VariableName}"but I was passing in VariableName with a suffix, like "abc.xml" which makes it interpret the .xml as some kind of format request instead. See answers there.

path = "/path/{VariableName}"但我传入带有后缀的 VariableName,例如“abc.xml”,这使其将 .xml 解释为某种格式请求。请参阅那里的答案。