Spring MVC - HttpMediaTypeNotAcceptableException



当使用Spring MVC和JSON时,我一直得到这个HttpMediaTypeNotAcceptableException错误的AJAX请求。错误的完整堆栈跟踪是…

 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

现在我完全不知道这里发生了什么。还有什么问题会导致这个错误…

请确保在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。希望能有所帮助

From:http://georgovassilis.blogspot.ca/2015/10/spring mvc -休息-控制器-说- 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>

确保将两个Jackson jar添加到classpath:

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

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

<mvc:annotation-driven />

因为这是第一个谷歌命中"HttpMediaTypeNotAcceptableException"我喜欢添加另一个问题,我偶然发现这导致了HttpMediaTypeNotAcceptableException太。

在我的例子中,它是一个指定"产生"的控制器,例如:

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

,因为我想提供XML文件。同时,我使用"@ControllerAdvice"类来捕获异常,例如,如果没有找到请求的文件。异常处理程序返回JSON,以便客户端(angular)应用可以在SPA的某个地方显示错误消息。

现在控制器想要返回XML,但是异常处理程序返回JSON,所以引发了HttpMediaTypeNotAcceptableException。我通过添加JSON尽可能"产生"值来解决这个问题:

produces = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE}

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

需要记住的重要事项:3.1.2之前的Spring版本与JACKSON 1兼容。x和NOT with JACKSON 2.x。这是因为从杰克逊一号开始。X到2。X类的包名被改变了。在杰克逊。x类在org.codehaus.jackson下,而在JACKSON 2中。

为了解决这个问题,从Spring 3.1.2开始,他们添加了一个新的MappingJackson2HttpMessageConverter来取代MappingJacksonHttpMessageConverter。

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

在我的案例中 favorpatheextension (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@dom.com`
}
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    configurer
            .favorPathExtension(false); // to  avoid HttpMediaTypeNotAcceptableException on standalone tomcat
}

}

在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");
}

错误就会消失。

我有同样的问题,但我已经发现,基本上发生了什么,当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;
    }
}

这就是我的工作方式

response.setHeader("Accept",  "application/json");

尝试添加"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},...

正如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。

在我的情况下,只需添加@ResponseBody注释即可解决此问题。

我的例子

 {"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作为某种格式的请求,而不是。见答案。

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

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

当你以。html结束url时,这意味着你将不接受除html以外的任何其他有效载荷。我需要从末尾删除.html以使我的端点正常工作。(你也可以在url后面加上。json,它也会起作用)

另外,需要正确配置web.xml中的url模式以允许您访问资源。对我来说是

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

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

更多的是评论而不是回答…

我正在使用龙bok,我正在开发一个(非常)骨架API,我的响应DTO没有任何字段(尚未),我在运行集成测试时得到了HttpMediaTypeNotAcceptableException错误。

在响应DTO中添加一个字段修复了这个问题。

相关内容

  • 没有找到相关文章

最新更新