47

与 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)

我做的小谷歌搜索表明请求应该包含类似“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

现在我完全迷失了这里发生的事情..这里还有什么可能出错来得到这个错误......

4

15 回答 15

51

请确保您的 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 的所有项目都应该有 getter/setter。希望能帮助到你

于 2011-08-25T21:35:39.177 回答
24

来自: 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 声明,你包括了 Jackson,基本上你被卡住了。更糟糕的是,它只会在 URL 路径中的某些电子邮件上吐出该错误,尤其是那些以“.com”域结尾的电子邮件。

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

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

解决方案是为 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>
于 2016-01-25T22:31:57.623 回答
19

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

  • 杰克逊-核心-asl-x.jar
  • jackson-mapper-asl-x.jar

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

<mvc:annotation-driven />
于 2011-12-27T15:15:41.457 回答
13

因为这是“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}

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

于 2017-03-24T10:33:24.087 回答
10

需要记住的重要一点: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 开始,他们添加了一个新的 MappingJackson2HttpMessageConverter 来替换 MappingJacksonHttpMessageConverter。

您可以在此链接中找到有关兼容性问题的更多详细信息:Jackson annotations being ignored in Spring

于 2013-05-01T21:08:01.013 回答
8

在我的情况下,喜爱路径扩展(假)帮助了我

@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@dom.com`
}

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

}

于 2017-12-12T12:02:09.257 回答
5

在扩展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 MappingJackson2HttpMessageConverter();
    converters.add(converter);
    logger.info("MappingJackson2HttpMessageConverter added");

}

并且错误将消失。

于 2015-05-11T07:59:21.030 回答
2

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

在我的课看起来像下面之前

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;
    }
}

这就是我的工作方式

于 2017-05-09T10:57:46.720 回答
1

尝试将“jackson-databind”罐子添加到 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},...

于 2018-02-08T09:51:24.453 回答
0
response.setHeader("Accept",  "application/json");
于 2013-01-13T10:18:39.343 回答
0

正如Alex在其中一个答案中暗示的那样,您可以使用 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。

于 2016-07-02T17:09:53.337 回答
0

就我而言,只需添加@ResponseBody注释即可解决此问题。

于 2017-07-27T07:32:17.057 回答
0

就我而言

 {"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”,这使它将.xml 解释为某种格式请求。在那里查看答案。

于 2018-09-20T22:15:13.560 回答
0

对我来说,问题是我试图访问的 URL。我有这样的网址:

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

当您以 .html 结束 url 时,这意味着您不会接受除 html 之外的任何其他有效负载。我需要从末尾删除 .html 才能使我的端点正常工作。(您也可以在 url 末尾附加 .json,它也可以使用)

此外,您的 url-patternweb.xml需要正确配置以允许您访问资源。对我来说是

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

以前我有*.html*,它阻止我访问端点。

于 2019-07-06T19:07:46.517 回答
0

更多的是评论而不是答案...

我正在使用 Lombok,我正在开发一个(非常)骨架 API,而我的响应 DTO 还没有任何字段,并且HttpMediaTypeNotAcceptableException在运行集成测试时出现错误。

向响应 DTO 添加字段解决了该问题。

于 2019-07-30T09:56:50.923 回答