在使用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)
我做的小google搜索显示请求应该包含类似“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
现在我完全迷失在这里发生的事情......这里还有什么问题可以解决这个错误......
答案 0 :(得分:48)
请确保您的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。 希望它有所帮助
答案 1 :(得分:21)
自: http://georgovassilis.blogspot.ca/2015/10/spring-mvc-rest-controller-says-406.html
您已获得此 Spring @RestController ,并将包含电子邮件的网址映射为网址路径的一部分。你狡猾地解决了点截断问题[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]非常棘手:应用服务器执行一些内容协商并说服 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>
答案 2 :(得分:19)
确保将两个Jackson jar添加到classpath:
此外,您必须在Spring xml文件中包含以下内容:
<mvc:annotation-driven />
答案 3 :(得分: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
答案 4 :(得分:9)
因为这是第一个针对“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}
希望这有助于其他人。 : - )
答案 5 :(得分:6)
在我的情况下 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@dom.com`
}
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer
.favorPathExtension(false); // to avoid HttpMediaTypeNotAcceptableException on standalone tomcat
}
}
答案 6 :(得分:4)
在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");
}
错误将消失。
答案 7 :(得分:2)
我遇到了同样的问题,但我已经弄清楚,当spring尝试渲染响应时会发生什么,它会尝试根据你指定的媒体类型序列化它,并在你的类中使用getter和setter方法
在我的课程看起来像下面之前
public class MyRestResponse{
private String message;
public void setMessage(String msg){
this.message = msg;
}
public String getMessage(){
return this.message;
}
}
解决方案如下所示
.place:hover ~ .anHour {
/*code here*/
}
它是如何为我工作的
答案 8 :(得分:1)
尝试添加&#34; jackson-databind&#34; jars到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},...
答案 9 :(得分: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
Etvoilà!现在SpringMVC找到方法,验证表单,并让你返回一个JSON POJO。
答案 10 :(得分:0)
就我而言,只需添加@ResponseBody
注释即可解决此问题。
答案 11 :(得分: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}"
,但是我传入了带有后缀的VariableName,例如“ abc.xml”,这使它将.xml解释为某种format request instead。在此处查看答案。
答案 12 :(得分:0)
对我来说,问题是我尝试访问的URL。我有这样的网址:
{{ip}}:{{port}}/{{path}}/person.html
当您使用.html结束url时,表示您将不接受除html之外的任何其他有效负载。我需要从末尾删除.html才能使端点正常工作。 (您也可以在网址末尾附加.json,它也可以使用)
另外,您的web.xml
中的url模式需要正确配置以允许您访问资源。对我来说是
<servlet-mapping>
<servlet-name>spring-mvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
以前我有*.html*
,这使我无法访问端点。
答案 13 :(得分:0)
评论多于答案...
我正在使用Lombok,并且正在开发(非常)骨架API,并且我的响应DTO还没有任何字段,并且在运行集成测试时遇到了HttpMediaTypeNotAcceptableException
错误。
在响应DTO中添加字段可解决此问题。
答案 14 :(得分:-2)
response.setHeader("Accept", "application/json");