Spring JSON request getting 406 (not Acceptable)
406 Not Acceptable
The resource identified by the request is only capable of generating response entities which have content characteristics not acceptable according to the accept headers sent in the request.
So, your request accept header is application/json and your controller is not able to return that. This happens when the correct HTTPMessageConverter can not be found to satisfy the @ResponseBody annotated return value. HTTPMessageConverter are automatically registered when you use the <mvc:annotation-driven>
, given certain 3-d party libraries in the classpath.
Either you don't have the correct Jackson library in your classpath, or you haven't used the<mvc:annotation-driven>
directive.
I successfully replicated your scenario and it worked fine using these two libraries and no headers="Accept=*/*"
directive.
- jackson-core-asl-1.7.4.jar
- jackson-mapper-asl-1.7.4.jar
406 Not acceptable error when returning JSON in Spring MVC
I could resolve the problem with my above code itself.
Problem was the jackson mapper jar was not present in the classpath.
So it was not working.
In Eclipse For Maven projects you have to force update such that the jar can come in the classpath.
Ideally there should been an error from the spring framework about the class not being loaded. The error itself was misleading.
Best Regards,
Saurav
Spring MVC + JSON = 406 Not Acceptable
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
That should be the problem. JSON is served as application/json
. If you set the Accept header accordingly, you should get the proper response. (There are browser plugins that let you set headers, I like "Poster" for Firefox best)
Spring MVC & JSON--406 Not Acceptable @Responsebody
Finally it's working now.First I have changed approach to do the same. Now instead of using form submit i'm using Ajax call as below:
$('#AddCustButton').click(function(){
var firstName = $('#first_name').val();
var lastName = $('#last_name').val();
var email = $('#email').val();
var phone = $('#phone').val();
var address = $('#address').val();
var city = $('#city').val();
var state = $('#state').val();
$.ajax({
url:'saveCustomer',
type:'POST',
dataType:'json',
data:{'first_name':firstName,'last_name':lastName,'email':email,'phone':phone,'address':address,'city':city,'state':state},
success:function(response){
if(response.status=='Success'){
$('#success_message').slideDown({ opacity: "show" }, "slow"); // Do something ...
$('#contact_form').data('bootstrapValidator').resetForm();
}
}
});
});
And then checked for the response but was getting the same error with status code 406.Then i got a clue to change the Codehus-Jackson libraries to FasterXml-Jackson From the comments of @Walfrat(see comments below the question) and from the 'Paul grime''s answer to this question
Question
After Changing from codehaus-Jackson to fasterXML-Jackson it's working.
RestController: HTTP Status 406 - Not Acceptable
Regarding 406 - Not Acceptable
Since your controller is configured to only return a response if the client requests application/json
data,
produces = "application/json"
you probably get "406 Not Acceptable" because your client requested something else / did not specify any Accepts header. You can fix by:
- fixing your client request to provide
Accepts
header - changing the annotation to accept whatever your clients send (inluding
*/*
if you are lazy).
This is your only issue, you are not forced to use any Serialization framework with Spring (But a Serializer is required if you define your controller methods to return arbitrary beans). You can write any String as a response to your clients.
Regarding how to respond with Jsoniter in the background
If you want to keep using Jsoniter, but move that to the background so your Controller class does not explicitly mention jsoniter anymore, you need to define your own custom HttpMessageConverter.
Regarding how to respond without Jsoniter
You need some Serializer to generate Json from Java. You can write custom code, or use Jackson or Gson. Spring supports Jackson by default, and Gson by using GsonHttpMessageConverter. For Jackson, your current code is ok, but you need to add a jackson dependency. For Gson, you need to declare the converter, there are several resources explaining that online.
Regarding how to manually respond with Jsoniter
As in the answers to this question Does spring mvc have response.write to output to the browser directly?
You can write your response using @ResponseBody
. Since @RestController
already implies @ResponseBody
, you could also leave it out. Showing it here just for clarification:
@ResponseBody // not needed with @RestController
@RequestMapping(value = "Test", method = RequestMethod.Get, produces = "application/json")
public String letsTest() {
// Using Jsoniter JsonStream
return JsonStream.serialize(myStringList);
}
Related Topics
Using Javamail to Connect to Gmail Smtp Server Ignores Specified Port and Tries to Use 25
Java Lib or App to Convert CSV to Xml File
Stack with Find-Min/Find-Max More Efficient Than O(N)
Converting List<Integer> to List<String>
How to Insert a Character in a String at a Certain Position
Having a 3Rd Party Jar Included in Maven Shaded Jar Without Adding It to Local Repository
Lambdaconversionexception with Generics: Jvm Bug
How to Monitor Java Memory Usage
Get Yesterday's Date Using Date
What Does This Expression Language ${Pagecontext.Request.Contextpath} Exactly Do in Jsp El
Exclude @Component from @Componentscan
Java Reflection: How to Get the All Getter Methods of a Java Class and Invoke Them
Why Is Javac Failing on @Override Annotation
"Non-Static Variable This Cannot Be Referenced from a Static Context" When Creating an Object