Spring MVC + JSON = 406 Not Allowed

I am trying to create a simple JSON response. Now I get a 406 invalid error. Tomcat says: "The resource identified by this request is able to generate responses with characteristics that are not acceptable according to the headers of the accept request. Even if my headers are Accept

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

In tomcat / lib I have all the Tomcat, Spring jars and jackson-all-1.9.0.jar mailboxes. I am using Spring 3.2.2 with Tomcat 7.

I know that this issue has been discussed many times, but none of the solutions work for me.

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> 

dispatcher-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; } } 

I have already tried adding

 <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> 

for my dispatcher-servlet.xml or jakcson-all changes for jackson-asl and jackson-core-asl, but the output was the same.

+46
java json spring
May 2 '13 at 10:21
source share
19 answers

Accept: Text / HTML, application / XHTML + XML, application / XML; d = 0.9, /; d = 0.8

That should be a problem. JSON is used as application/json . If you set the Accept header appropriately, you should get the right answer. (There are browser plugins that allow you to set headers, I like Firefox "Poster" best)

+16
May 2 '13 at 11:48
source share

If you are using Maven and the latest Jackson code , you can remove the entire Jackson configuration from your spring XML configuration files (you will still need the <mvc: annotation-driven /> tag driven by annotations) and just add some Jackson dependencies to your pom file .xml. The following are examples of dependencies. This worked for me and I use:

  • Apache Maven 3.0.4 (r1232337; 2012-01-17 01: 44: 56-0700)
  • org.springframework version 3.1.2.RELEASE
  • 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>... 
+36
Oct 25 '13 at 15:34
source share

Another way to get this error is to create a class without public members. 406 is not acceptable - this is a pretty useless error message in this scenario.

+18
Apr 02
source share

With Spring 4, you add @EnableWebMvc , for example:

 @Controller @EnableWebMvc @RequestMapping(value = "/articles/action", headers="Accept=*/*", produces="application/json") public class ArticlesController { } 
+8
May 15 '15 at 17:53
source share

None of the answers helped me.

I read dozens of Stackoverflow answers about 406 Not Acceptable, HttpMediaTypeNotAcceptableException, multipart file, ResponseBody, setting Accept headers, produces, consumes, etc.

We had Spring 4.2.4 with SpringBoot and Jackson configured in build.gradle:

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

All routes worked fine in our other controllers, and we could use GET, POST, PUT and DELETE. Then I started adding multi-user file upload capabilities and created a new controller. GET routes work fine, but our POST and DELETE did not. No matter how I tried different solutions from here on SO, I just kept getting 406 invalid ones.

Then finally I stumbled upon this answer: Spring throw HttpMediaTypeNotAcceptableException: could not find an acceptable view because of a dot in the url

Read Ranisa's answer and all the comments.

It all came down to our @RequestMapping values:

 @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); } 

The part {fileName:.+} In the @RequestMapping value caused 406 invalid ones in our case.

Here is the code I added from Ranis's answer:

 @Configuration public class ContentNegotiationConfig extends WebMvcConfigurerAdapter { @Override void configureContentNegotiation(final ContentNegotiationConfigurer configurer) { // Turn off suffix-based content negotiation configurer.favorPathExtension(false); } } 

EDIT August 29, 2016:

We were having problems using configurer.favorPathExtension(false) : static SVG images stopped loading. After analysis, we found that Spring started sending SVG files back to the user interface with the type "application / octet-stream" of the content type instead of "image / svg + xml". We solved this by sending fileName as the request parameter, for example:

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

We also removed configurer.favorPathExtension(false) . Another way might be to encode fileName in a way, but we have chosen the request parameter method to avoid additional side effects.

+7
Jul 21 '16 at 10:21
source share

Use the dependency below in your pom

 <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.5.3</version> </dependency> 
+6
Apr 08 '16 at 7:27
source share

You need to register the annotation binding for Jackson in your spring -mvc-config.xml, for example:

 <!-- 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> 

Then in your controller you can use:

 @RequestMapping(value = "/your_url", method = RequestMethod.GET, produces = "application/json") @ResponseBody 
+4
May 2 '13 at 12:57
source share

I believe the problem was using the * .htm extension in RequestMapping ( foobar.htm ). Try changing it to footer.json or something else.

Link to the correct answer: stack overflow

PS

It's okay for Spring to do something by default, regarding the fact that developers know the entire Spring API from A to Z. And then just “406 is unacceptable” without any details, and Tomcat logs are empty

+4
Jul 10 '14 at 9:52
source share

See the problem with the extension. Depending on the extension, spring may determine the type of content. If your URL ends with .com , it sends the text / html as the content header. If you want to change this Spring behavior, use the code below:

 @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(); } } 

Here we set the favorPathExtension parameter to false and the Default Content-type for Application / json. Note. The HibernateConfig class contains all beans.

+2
Apr 28 '16 at 18:49
source share

Try to add

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

on getShopInJSON() .

It worked for me.

+1
Apr 09 '15 at 12:07
source share

Perhaps all fields of your POJO need Getter and Setter.

I fixed it according to this problem. reference: Spring MVC - HttpMediaTypeNotAcceptableException

And 406 is not a helpful message for fixing a bug. You must debug the codes and see what the Exception is on earth.

+1
Apr 20 '16 at 12:09 on
source share

this is because the object is not acceptable for jsp ... use it

add this dependency or any other passed converted json string to jsp ...

for example add this to pom

 <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.6.2</version> </dependency> 

and use this code:

 @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 
+1
Jul 28 '16 at 8:00
source share

Today I also experienced the same problem. In my case in web.xml I have

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

my url has the extension .html . Example: .../getUsers.html . But I am returning JSON data to the controller..html will by default set accept type as html.

So, I changed to the following:

web.xml:

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

URL:

.../getUsers.json

Now everything is working fine. Hope this helps.

+1
Mar 28 '17 at 12:06 on
source share

It looks like you are trying to create / get json output. I see two problems with your approach. 1) You did not specify the application / json in the Accept header 2) You need to specify output = "application / json" in @RequestMapping

0
Jan 10 '15 at
source share

There is another case where this status will be returned: if the Jackson tablet cannot figure out how to serialize your bean. For example, if you have two access methods for the same boolean property, isFoo() and getFoo() .

removed getFoo() and put isFoo() . it worked for me.

0
Jan 28 '15 at 6:58
source share

I couldn't see this as an answer here, so I thought I wanted to mention that I got this error using spring 4.2 when I accidentally deleted getter / setter for the class that I expected to return as Json.

0
Oct 20 '15 at 9:40
source share

The value of My RequestMapping ended with .html , which should be something else.

I tried changing it to .json and it worked for me.

0
Aug 11 '16 at 10:43 on
source share

I have a similar problem and resolved with the code below

 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. 
0
Sep 13 '16 at 20:09
source share

My class was annotated using JsonSerialize, and the include parameter was set to JsonSerialize.Inclusion.NON_DEFAULT . This made Jackson determine the default values ​​for each bean property. I had a bean property that returned an int. In my case, the problem was that the bean gatekeeper made a call to a method that has a return type (i.e. a General method). For some odd reason, this code is compiled; it should not compile because you cannot use int for the return type of return. I changed "int" to "Integer" for this bean property, and I no longer have 406. Honestly, now the code cannot compile if I changed Integer to int.

0
Oct 26 '17 at 18:43 on
source share



All Articles