Spring MVC + JSON = 406不可接受

我试图生成一个简单的JSON响应工作。 现在我得到406不可接受的错误。 Tomcat说:“这个请求标识的资源只能根据请求的”接受“头文件生成不可接受的特征的响应。 即使我的Accept头是

 Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 

在Tomcat / lib中,我有所有的Tomcatjar子,Springjar子和jackson-all-1.9.0.jar。 我在Tomcat 7中使用Spring 3.2.2。

我知道这个问题已经讨论过很多次了,但是没有任何一个解决scheme为我工作。

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-全部jackson-asljackson-core-asl,但输出是相同的。

接受:text / html,application / xhtml + xml,application / xml; q = 0.9, / ; q = 0.8

这应该是问题。 JSON作为application/json 。 如果你相应地设置Accept头,你应该得到正确的回应。 (有浏览器插件,可以让你设置标题,我喜欢Firefox的“海报”最好)

如果您使用的是Maven和最新的Jackson代码,那么您可以从SpringconfigurationXML文件中删除所有Jackson特有的configuration(您仍然需要一个注释驱动标签<mvc:annotation-driven />),然后添加一些jackson依赖你的pom.xml文件。 请参阅下面的依赖关系的示例。 这工作对我来说,我正在使用:

  • Apache Maven 3.0.4(r1232337; 2012-01-17 01:44:56-0700)
  • org.springframework version 3.1.2.RELEASE
  • spring-security版本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>... 

你可以得到这个错误的另一种方法是创build一个没有公共成员的类。 在这种情况下406不可接受是一个相当无用的错误消息。

在Spring 4中,只能添加@EnableWebMvc ,例如:

 @Controller @EnableWebMvc @RequestMapping(value = "/articles/action", headers="Accept=*/*", produces="application/json") public class ArticlesController { } 

没有其他的答案帮助我。

我读了几十个关于406不可接受,HttpMediaTypeNotAcceptableException,多部分文件,ResponseBody,设置接受标题,产生,消耗等的Stackoverflow答案

我们用SpringBoot和Jackson在build.gradle中configuration了Spring 4.2.4:

 compile "com.fasterxml.jackson.core:jackson-core:2.6.7" compile "com.fasterxml.jackson.core:jackson-databind:2.6.7" 

所有的路由在我们的其他控制器中工作正常,我们可以使用GET,POST,PUT和DELETE。 然后,我开始添加多部分file uploadfunction,并创build了一个新的控制器。 GETpath工作正常,但我们的POST和DELETE没有。 无论我如何从这里尝试不同的解决scheme,我只是不断得到406不能接受。

然后最后我偶然发现这个答案: spring抛出HttpMediaTypeNotAcceptableException:无法find可接受的表示forms,由于urlpath中的点

阅读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 Not Acceptable。

这里是我从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文件到内容types为“application / octet-stream”而不是“image / svg + xml”的UI。 我们通过发送fileName作为查询参数解决了这个问题,如:

 @RequestMapping(value = "/audio", method = RequestMethod.DELETE) public Boolean deleteAudio(@RequestParam String fileName) { return audioService.remove(fileName); } 

我们也删除了configurer.favorPathExtension(false) 。 另一种方法可能是在path中编码fileName,但我们select查询参数方法来避免进一步的副作用。

在你的pom中使用下面的依赖关系

 <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.5.3</version> </dependency> 

您必须在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 

我想,问题是在RequestMapping( foob​​ar.htm )中使用* .htm扩展。 尝试将其更改为footer.json或其他东西。

链接到正确的答案: https : //stackoverflow.com/a/21236862/537246

PS

默认情况下,Spring的方式是,开发人员知道Spring的整个API从A到Z,然后就是“406不能接受”,而Tomcat的日志是空的!

看到问题是与扩展。 根据扩展名,弹簧可以计算出内容types。 如果您的url以.com结尾,那么它将发送text / html作为内容types标题。 如果你想改变这个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。

尝试添加

 @RequestMapping(method = RequestMethod.GET,headers = {"Accept=text/xml, application/json"}) 

getShopInJSON()

它为我工作。

也许POJO的所有领域都需要Getter和Setter。

我根据这个问题修好了。 参考: Spring MVC – HttpMediaTypeNotAcceptableException

而406是不是一个有用的信息来解决这个错误。 你应该debugging代码,看看exception是在地球上。

这是因为jsp的对象是不能接受的…用他的

添加这个依赖或任何其他发送转换jsonstring到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 

今天我也经历了同样的问题。 在我的情况下,在web.xml我有

  <servlet-mapping> <servlet-name>spring</servlet-name> <url-pattern>*.html</url-pattern> </servlet-mapping> 

我的url是.html扩展名。 例如: .../getUsers.html 。 但是我在控制器中返回JSON数据。 .html扩展名默认将接受types设置为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

现在一切正常。 希望它有帮助。

它看起来像你正试图产生/接收JSON输出。 我看到你的方法有两个问题。 1)您没有在Accept头中指定application / json 2)您需要在@RequestMapping中指定produce =“application / json”

还有另外一种情况是返回这个状态:如果jackson映射器无法弄清楚如何序列化你的bean。 例如,如果对同一个boolean属性isFoo()和getFoo()有两个访问方法。

删除getFoo()并把isFoo()。 它为我工作。

我不能在这里看到它作为答案,所以我想我会提到,我收到这个错误使用spring4.2时,我不小心删除了类的getter / setter我期待被返回为Json。

我的RequestMapping值以.html结尾,应该是不同的。

我试图改变它.JSON和它为我工作。

我有类似的问题,并通过使用下面的代码解决

 public class ProductList { private List<Product> productList = new ArrayList<Product>(); @JsonProperty("data") @JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.WRAPPER_OBJECT) public List<Product> getProductList() { return productList; } public void setProductList(List<Product> productList) { this.productList = productList; } I am setting ProductList object in ResponseEntity object and returning from controller. 

我的类用JsonSerialize注释,并且include参数被设置为JsonSerialize.Inclusion.NON_DEFAULT 。 这导致了jackson确定每个bean属性的默认值。 我有一个返回int的bean属性。 在我的情况下,问题是bean getter调用了一个推断返回types的方法(即:一个通用的方法)。 由于一些奇怪的原因,这个代码编译; 它不应该编译,因为你不能使用int作为推断的返回types。 我把那个“int”改成了这个bean属性的一个“Integer”,我不再拥有一个406.奇怪的是,如果我将Integer改回到int,代码现在无法编译。