Spring MVC : The request sent by the client was syntactically incorrect
Asked Answered
L

7

6

When sending JSON requests to the server, I'm often greeted by this message:

The request sent by the client was syntactically incorrect ().

Usually it's an incorrect attribute that was passed that the controller didn't expect, since the object the JSON maps to doesn't contain it.

Finding the parameter is needlessly time consuming - is there a way to get more information, perhaps even a stack trace of the exception? I've tried running in debug mode and I'm using Jackson as my JSON (de)serialiser.

Lacy answered 20/10, 2012 at 17:2 Comment(3)
Try changing the loggin level (assuming you are using log4j or equiv.) of org.springframework to DEBUG.Scholar
Error The request sent by the client was syntactically incorrect"* in most of the case means that jackson is not able to desalinize(convert json string to object) because default constructor is missing. In your case there is missing default constructor, you have parameterized constructor which override default and jackson is not able create objectGynophore
Thanks man! That solved my problem.Toul
E
7

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);
Erleneerlewine answered 3/2, 2013 at 7:20 Comment(5)
@Aram Kocharyan did you try thisErleneerlewine
@JsonIgnoreProperties(ignoreUnknown = true) Worked for meIcecold
Error The request sent by the client was syntactically incorrect"* in most of the case means that jackson is not able to desalinize(convert json string to object) because default constructor is missing.Gynophore
#22050542Gynophore
@Gynophore This is a generic error thrown.please refer to OP question he clearly stated that this error occurred when an extra attributes are present in the Json structure.Hence the solution i proposed stands validErleneerlewine
O
9

To get more info / stack trace turn on debug logging for spring web in log4j.properties

log4j.logger.org.springframework.web=debug

Obvert answered 21/7, 2014 at 1:44 Comment(1)
Thank you very much, this is what I was looking for (y)Painting
E
7

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);
Erleneerlewine answered 3/2, 2013 at 7:20 Comment(5)
@Aram Kocharyan did you try thisErleneerlewine
@JsonIgnoreProperties(ignoreUnknown = true) Worked for meIcecold
Error The request sent by the client was syntactically incorrect"* in most of the case means that jackson is not able to desalinize(convert json string to object) because default constructor is missing.Gynophore
#22050542Gynophore
@Gynophore This is a generic error thrown.please refer to OP question he clearly stated that this error occurred when an extra attributes are present in the Json structure.Hence the solution i proposed stands validErleneerlewine
P
3

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\"}" 
Photoplay answered 20/2, 2013 at 12:41 Comment(1)
Most examples are using -d '{"x":"y"}', on Windows it does not work, and I had to use your way to make it work. Thx for posting.Oleoresin
M
0

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/fhbjgbiflinjbdggehcddcbncdddomop?hl=en) really helped in testing my changes pretty fast.

Midwife answered 26/8, 2015 at 15:4 Comment(0)
R
0

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.

Robenarobenia answered 28/5, 2016 at 10:50 Comment(1)
Welcome to StackOverflow. You must more detail your response for more helping user's issue.Collincolline
F
0

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.

Fistic answered 20/9, 2017 at 14:12 Comment(0)
A
0

In my case I had passed String value into a Integer type field.

I have solved this by creating another field of type String in the entity class and in the database Table and pass the value into this field.

Ator answered 15/7, 2022 at 11:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.