我正在尝试生成一个简单的JSON响应。现在我得到406 Not Acceptable错误。 Tomcat说:“此请求标识的资源只能根据请求”接受“标题生成具有不可接受特征的响应。”即使我的Accept
标题是
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
在tomcat / lib中我有所有Tomcat jar,Spring jar和jackson-all-1.9.0.jar。我在Tomcat 7中使用Spring 3.2.2。
我知道这个问题已经多次讨论过了,但没有一个解决方案适合我。
的web.xml
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Spring Web MVC Application</display-name>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
</web-app>
调度-servlet.xml中
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
<property name="prefix">
<value>/WEB-INF/pages/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<context:component-scan base-package="com.smiechmateusz.controller" />
<context:annotation-config />
<mvc:annotation-driven />
</beans>
HelloWorldController.java
package com.smiechmateusz.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
import com.smiechmateusz.dao.Foo;
@Controller
@RequestMapping("/")
public class HelloWorldController extends AbstractController{
@Override
protected ModelAndView handleRequestInternal(HttpServletRequest request,
HttpServletResponse response) throws Exception {
ModelAndView model = new ModelAndView("HelloWorldPage");
return model;
}
@RequestMapping(value="foobar.htm", method = RequestMethod.GET)
public @ResponseBody Foo getShopInJSON() {
Foo f = new Foo();
f.setX(1);
f.setY(2);
f.setDescription("desc");
return f;
}
}
Foo.java
package com.smiechmateusz.dao;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="foobaz")
public class Foo implements Serializable
{
private int x, y;
String description;
int id;
@Column(name = "x")
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
@Column(name = "y")
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
@Column(name = "description")
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Id @GeneratedValue
@Column(name = "id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
我已经尝试添加
了<bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jsonConverter"/>
</list>
</property>
</bean>
到我的 dispatcher-servlet.xml 或将 jakcson-all 更改为 jackson-asl 和 jackson-core-asl < / em>但输出相同。
答案 0 :(得分:38)
如果你正在使用Maven和最新的Jackson code,那么你可以从你的弹簧配置XML文件中删除所有特定于Jackson的配置(你仍然需要一个注释驱动的标签&lt; mvc:annotation-驱动/&gt;)并简单地将一些Jackson依赖项添加到您的pom.xml文件中。请参阅下面的依赖项示例。这对我有用,我正在使用:
spring-security version 3.1.0.RELEASE。
...<dependencies>
...
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.2.3</version>
</dependency>
...
</dependencies>...
答案 1 :(得分:20)
您可以获得此错误的另一种方法是创建一个没有公共成员的类。在这种情况下,406不可接受是一个非常无用的错误消息。
答案 2 :(得分:17)
接受:text / html的,应用/ XHTML + xml的,应用/ XML; Q = 0.9, / 的; Q = 0.8
这应该是问题所在。 JSON作为application/json
提供。如果相应地设置Accept标头,则应该得到正确的响应。 (有浏览器插件可以让你设置标题,我最喜欢Firefox的“海报”)
答案 3 :(得分:9)
其他答案都没有帮助我。
我阅读了大量有关406 Not Acceptable,HttpMediaTypeNotAcceptableException,multipart文件,ResponseBody,设置Accept标头,生成,消耗等的Stackoverflow答案。
我们使用Spring 4.2和Spring配置了Spring.Boot:
compile "com.fasterxml.jackson.core:jackson-core:2.6.7"
compile "com.fasterxml.jackson.core:jackson-databind:2.6.7"
我们的其他控制器中的所有路由都运行正常,我们可以使用GET,POST,PUT和DELETE。然后我开始添加多部分文件上传功能并创建一个新的控制器。 GET路由工作正常但我们的POST和DELETE没有。无论我如何从这里尝试不同的解决方案,我只是不断获得406不可接受。
然后我终于偶然发现了这个答案: Spring throwing HttpMediaTypeNotAcceptableException: Could not find acceptable representation due to dot in url path
阅读Raniz的回答和所有评论。
这一切都归结为我们的@RequestMapping值:
@RequestMapping(value = "/audio/{fileName:.+}", method = RequestMethod.POST, consumes="multipart/*")
public AudioFileDto insertAudio(@PathVariable String fileName, @RequestParam("audiofile") MultipartFile audiofile) {
return audioService.insert(fileName, audiofile);
}
@RequestMapping(value = "/audio/{fileName:.+}", method = RequestMethod.DELETE)
public Boolean deleteAudio(@PathVariable String fileName) {
return audioService.remove(fileName);
}
@RequestMapping值中的{fileName:.+}
部分导致我们的情况下406不可接受。
这是我从Raniz的回答中添加的代码:
@Configuration
public class ContentNegotiationConfig extends WebMvcConfigurerAdapter {
@Override
void configureContentNegotiation(final ContentNegotiationConfigurer configurer) {
// Turn off suffix-based content negotiation
configurer.favorPathExtension(false);
}
}
编辑2016年8月29日:
我们使用configurer.favorPathExtension(false)
遇到了麻烦:静态SVG图片停止加载。经过分析,我们发现Spring开始将SVG文件发送回UI,内容类型为“application / octet-stream”,而不是“image / svg + xml”。我们通过将fileName作为查询参数发送来解决此问题,例如:
@RequestMapping(value = "/audio", method = RequestMethod.DELETE)
public Boolean deleteAudio(@RequestParam String fileName) {
return audioService.remove(fileName);
}
我们还删除了configurer.favorPathExtension(false)
。另一种方法是在路径中编码fileName,但我们选择查询参数方法以避免进一步的副作用。
答案 4 :(得分:9)
使用Spring 4,您只需添加@EnableWebMvc
,例如:
@Controller
@EnableWebMvc
@RequestMapping(value = "/articles/action", headers="Accept=*/*", produces="application/json")
public class ArticlesController {
}
答案 5 :(得分:6)
在你的pom中使用以下依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.3</version>
</dependency>
答案 6 :(得分:5)
您必须在spring-mvc-config.xml中注册Jackson的注释绑定,例如:
<!-- activates annotation driven binding -->
<mvc:annotation-driven ignoreDefaultModelOnRedirect="true" validator="validator">
<mvc:message-converters>
<bean class="org.springframework.http.converter.ResourceHttpMessageConverter"/>
<bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"/>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
然后在你的控制器中你可以使用:
@RequestMapping(value = "/your_url", method = RequestMethod.GET, produces = "application/json")
@ResponseBody
答案 7 :(得分:4)
我想,问题是在RequestMapping( foobar.htm )中使用 * .htm 扩展名。尝试将其更改为 footer.json 或其他内容。
指向正确答案的链接:https://stackoverflow.com/a/21236862/537246
P.S。
默认情况下,Spring的方式是开发人员从A到Z知道Spring的整个API。然后只是&#34; 406不能接受&#34;没有任何细节,Tomcat的日志都是空的!
答案 8 :(得分:2)
看问题是扩展名。根据扩展名,spring可以找出内容类型。如果您的网址以 .com 结尾,则会将 text / html 作为内容类型标头发送。如果要更改Spring的此行为,请使用以下代码:
@Configuration
@Import(HibernateConfig.class)
@EnableWebMvc
// @EnableAsync()
// @EnableAspectJAutoProxy
@ComponentScan(basePackages = "com.azim.web.service.*", basePackageClasses = { WebSecurityConfig.class }, excludeFilters = { @ComponentScan.Filter(Configuration.class) })
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(false).favorParameter(true).parameterName("mediaType").ignoreAcceptHeader(true).useJaf(false)
.defaultContentType(MediaType.APPLICATION_JSON).mediaType("xml", MediaType.APPLICATION_XML).mediaType("json", MediaType.APPLICATION_JSON);
}
@Bean(name = "validator")
public Validator validator() {
return new LocalValidatorFactoryBean();
}
}
在这里,我们将favorPathExtension设置为false,将Default Content-type设置为Application / json。 注意: HibernateConfig类包含所有bean。
答案 9 :(得分:2)
今天我也经历了同样的问题。在我的情况下,在web.xml
我有
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
我的网址有.html
分机。实施例:.../getUsers.html
。但是我在控制器中返回JSON数据。 .html扩展名默认将accept类型设置为html。
所以我改为:
<强>的web.xml:强>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>*.html</url-pattern>
<url-pattern>*.json</url-pattern>
</servlet-mapping>
<强> URL:强>
.../getUsers.json
现在一切正常。希望它有所帮助。
答案 10 :(得分:1)
尝试添加
@RequestMapping(method = RequestMethod.GET,headers = {"Accept=text/xml, application/json"})
on getShopInJSON()
。
它对我有用。
答案 11 :(得分:1)
也许你的POJO的所有领域都需要Getter和Setter。
我根据这个问题修复了它。 参考:Spring MVC - HttpMediaTypeNotAcceptableException
406并不是修复bug的有用信息。您应该调试代码并查看地球上的异常情况。
答案 12 :(得分:1)
这是因为在jsp中对象是不可接受的...使用他的
将此依赖项或任何其他发送转换的json字符串添加到jsp ...
例如,在pom中添加此内容
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.6.2</version>
</dependency>
并使用类似的代码:
@RequestMapping(value="foobar.htm", method = RequestMethod.GET)
public @ResponseBody String getShopInJSON() {
Foo f = new Foo();
f.setX(1);
f.setY(2);
f.setDescription("desc");
return new Gson().toJson(f); //converted object into json string
}//return converted json string
答案 13 :(得分:0)
还有另一种情况会返回此状态:如果Jackson映射器无法弄清楚如何序列化bean。例如,如果对同一布尔属性有两个访问器方法,isFoo()
和getFoo()
。
已移除getFoo()
并放置isFoo()
。它对我有用。
答案 14 :(得分:0)
我无法在这里看到它作为答案所以我想我会提到我使用Spring 4.2收到了这个错误,因为我不小心删除了我希望作为Json返回的类的getter / setter。
答案 15 :(得分:0)
看起来您正在尝试生成/接收json输出。 我看到你的方法有两个问题。 1)您没有在Accept标头中指定application / json 2)您需要指定produce =&#34; application / json&#34;在你的@RequestMapping
中答案 16 :(得分:0)
我的RequestMapping
值以 .html 结尾,这应该是不同的。
我尝试将其更改为 .json ,这对我有用。
答案 17 :(得分:0)
我遇到了类似的问题,并使用下面的代码
解决了<tr>
答案 18 :(得分:0)
我的类使用JsonSerialize注释,include参数设置为JsonSerialize.Inclusion.NON_DEFAULT
。这导致Jackson确定每个bean属性的默认值。我有一个返回int的bean属性。我的问题是bean getter调用了一个具有推断返回类型的方法(即:一般方法)。由于某些奇怪的原因,这个代码编译它不应该编译,因为你不能使用int作为推断的返回类型。我改变了&#39; int&#39;到一个整数&#39;对于那个bean属性,我不再有406.奇怪的是,如果我将Integer更改回int,代码现在无法编译。
答案 19 :(得分:0)
因为它是此错误的最佳答案,所以我在这里添加XML的大小写。
返回的对象还可能没有正确定义XML结构。对我来说就是这种情况。
public @ResponseBody DataObject getData(
尽管标头正确,也会抛出相同的错误。 当我将@XmlRootElement添加到对象的标题时,错误停止了:
@XmlRootElement
public class DataObject {
@XmlElement(name = "field", nillable = true)
protected String field;
答案 20 :(得分:0)
我遇到了同样的问题,就我而言,我的xxx-servlet.xml配置文件中缺少以下内容
<mvc:annotation-driven/>
我一经添加就可以了。