When sending JSON requests to the server, I\'m often greeted by this message:
The request sent by the client was syntactically incorrect ().
This error can also occur when using nested classes e.g.
class One {
some code..
public class NestedOne {
private attr;
public NestedOne() {
// default constructor
}
}
}
and then having
@RequestMapping(value = "/something")
public String someControllerMethod(@RequestBody One.NestedOne nested) {
...
}
jackson then doesn't recognize NestedOne() as default constructor and searches for One.NestedOne() constructor.
I was facing the same error since couple of days, finally enabled the debug logging as mentioned by @Farm and was able to see the cause of this issue. I had a Person Object being posted in json from jsp to spring controller as shown below:-
@RequestMapping(value = "/get", method = RequestMethod.POST)
public @ResponseBody
Person getPerson(@RequestBody Person person) {
// System.out.println("inside get::::::::");
System.out.println("city:=" + person.getResidenceAddress().getCity()+" "
+ "name:= " + person.getFullName().getFirstName());
// Person prsn = personService.getPerson(person);
/*
* Person prsn = new Person(); prsn.setId(1); ResponseDecorator rd = new
* ResponseDecorator(prsn, true);
*/return person;
}
// Person Object
class Person{
private Name fullName;
private Address residenceAddress;
private Address mailingAddress;
private Gender gender;
private MaritalStatus maritalStatus;
private Integer creditRating;
}
//Address Object
public class Address {
private String streetNo;
private String streetName;
private String suburb;
private String city;
private String state;
private String country;
private Integer pinCode;
private AddressType addressType;
}
json post from jsp:-
//create JSON
var json = {
"id": id,
"fullName":{"firstName":firstName,"middleName":middleName,"surName": surName},
"residenceAddress":{ "streetNo": streetNo,
"streetName": streetName,
"suburb": suburb,
"city": city,
"state": state,
"country": country,
"pinCode": pincode
}
};
var dataString = JSON.stringify(json);
//alert(dataString);
$.ajax({
headers: {
Accept : "text/plain; charset=utf-8, application/json"},
url: "/myservice/get",
type: 'POST',
dataType: 'json',
//data : "{ }",
data: dataString,
contentType: 'application/json',
mimeType: 'application/json',
success: function(data) {
alert(data);
},
error:function(data,status,er) {
alert("error: "+data+" status: "+status+" er:"+er);
}
});
The error on submit was 400 Bad request and there was no other clue as to why it was failing. On enabling the debug mode on the server, I could see the below error stack trace:-
**00:53:42,294 DEBUG RequestResponseBodyMethodProcessor:117 - Reading [com.foo.assignment.model.Person] as "application/json" using [org.springframework.http.converter.json.MappingJacksonHttpMessageConverter@1813fb]
00:53:42,310 DEBUG ServletInvocableHandlerMethod:159 - Error resolving argument [0] [type=com.foo.assignment.model.Person]
HandlerMethod details:
Controller [com.foo.assignment.controller.PersonController]
Method [public com.foo.assignment.model.Person com.foo.assignment.controller.PersonController.getPerson(com.foo.assignment.model.Person)]
org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: No suitable constructor found for type [simple type, class com.foo.assignment.model.Address]: can not instantiate from JSON object (need to add/enable type information?)
at [Source: org.apache.catalina.connector.CoyoteInputStream@f264df; line: 1, column: 98] (through reference chain: com.foo.assignment.model.Person["residenceAddress"]); nested exception is org.codehaus.jackson.map.JsonMappingException: No suitable constructor found for type [simple type, class com.foo.assignment.model.Address]: can not instantiate from JSON object (need to add/enable type information?)
at [Source: org.apache.catalina.connector.CoyoteInputStream@f264df; line: 1, column: 98] (through reference chain: com.foo.assignment.model.Person["residenceAddress"])
at org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.readInternal(MappingJacksonHttpMessageConverter.java:127)
at org.springframework.http.converter.AbstractHttpMessageConverter.read(AbstractHttpMessageConverter.java:153)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:120)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:91)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:71)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:74)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:155)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:117)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:900)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:827)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:957)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:620)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:722)
Caused by: org.codehaus.jackson.map.JsonMappingException: No suitable constructor found for type [simple type, class com.foo.assignment.model.Address]: can not instantiate from JSON object (need to add/enable type information?)
at [Source: org.apache.catalina.connector.CoyoteInputStream@f264df; line: 1, column: 98] (through reference chain: com.foo.assignment.model.Person["residenceAddress"])
at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:163)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObjectUsingNonDefault(BeanDeserializer.java:746)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:683)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:580)
at org.codehaus.jackson.map.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:299)
at org.codehaus.jackson.map.deser.SettableBeanProperty$MethodProperty.deserializeAndSet(SettableBeanProperty.java:414)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:697)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:580)
at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:2732)
at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1923)
at org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.readInternal(MappingJacksonHttpMessageConverter.java:124)
... 37 more
00:53:42,310 DEBUG ExceptionHandlerException**
Adding a default constructor in the Address object solved the error. And using Google add-on Postman(plugin https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncffffdomop?hl=en) really helped in testing my changes pretty fast.
To get more info / stack trace turn on debug logging for spring web in log4j.properties
log4j.logger.org.springframework.web=debug
If the data that your consuming is from an external api and if you want to shield your controller from unnecessary elements/properties that you dont need you can use below annotation on POJO class
@JsonIgnoreProperties(ignoreUnknown = true)
or you could set it globally
//jackson 2.0
jsonObjectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
The issue is with your POJO, keep the server log level to Debug level and check the error. This will be mostly related to some field and field-type mismatch.
Old case, my be irrelevant by now, but for others with similar trouble I'll add this entry.
Check that you have double quotes, not single quotes. Also try escaping them.
I used the app curl for my test json requests.
My JSON was like this
{ 'name' : 'somedata', 'town':'some town' }
and it just blew up in my eyes.
"The request sent by the client was syntactically incorrect" was the general error. So I changed it from single quotes to double quotes, no go. I then tried having a backslash infront of the single quotes, still no go. Then changed it to backslash infront of the double quotes and presto!
curl -i -H "Accept: application/json" -H "Content-Type: application/json" \
http://localhost:8077/dra/dump.json \
-X PUT -d "{\"name\" : \"My Name\", \"town\":\"My Town\"}"