当使用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中添加一个字段修复了这个问题。