Ad

Jackson Could Not Read Document: Unrecognized Token 'contactForm': Was Expecting ('true', 'false' Or 'null')

- 1 answer

I want to send a POST request with JQuery to a Spring Controller but i keep getting this error from jquery

Could not read document: Unrecognized token 'contactForm': was expecting ('true', 'false' or 'null')
 at [Source: [email protected]; line: 1, column: 13]; nested exception is com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'contactForm': was expecting ('true', 'false' or 'null')
 at [Source: [email protected]; line: 1, column: 13]

This is the POST request

$('#contactForm').on('submit', function(e){
        e.preventDefault();
        var contactForm = new Object;
        var firstName = $('#firstName').val();
        var lastName = $('#lastName').val();
        var email = $('#email').val();
        var message = $('#message').val();
        contactForm.firstName = firstName;
        contactForm.lastName = lastName;
        contactForm.email = email;
        contactForm.message = message;
        contactForm.accepted = true;
        console.log(JSON.stringify(contactForm));
        $.ajax({
            type: 'POST',
            url: '/checkContact.json',
            contentType : 'application/json; charset=utf-8',
            dataType: 'json',
            data: {
                contactForm: JSON.stringify(contactForm)

            },
            success: function(response){
                console.log(response)
                $('#success').text(response.message);
            },
            error: function(data){
                console.log(data.responseJSON.message);
            }
        })
    })

and this is the controller

 @PostMapping("/checkContact.json")
       public @ResponseBody String sendContactForm(@Valid @RequestBody ContactForm contactForm, BindingResult result, HttpServletRequest request) throws MalformedURLException, JsonProcessingException{

//logic here

}

And ContactForm

public class ContactForm {

    @NotNull
    @NotEmpty
    @ValidEmail
    private String email;

    @NotNull
    @NotEmpty
    private String firstName;

    @NotNull
    @NotEmpty
    private String lastName;

    @NotNull
    @NotEmpty
    private String message;

//  @AssertTrue
    private boolean accepted;

//getters and setters
}

I don't know exactly what is happening, because if I, for instance, try to send to the controller a JSON with POSTMAN with this body, which is the same of the JSON.stringify(contactForm), everything goes well, so Jackson is doing something strange behind the scenes...

{
    "fistName": "John",
    "lastName": "Smith",
    "email": "[email protected]",
    "message": "Hello"
    "accepted":true
}
Ad

Answer

In your jQuery ajax call adjust your data value:

    $.ajax({
        type: 'POST',
        url: '/checkContact.json',
        contentType : 'application/json; charset=utf-8',
        dataType: 'json',
        data: JSON.stringify(contactForm),
        success: function(response){
            console.log(response)
            $('#success').text(response.message);
        },
        error: function(data){
            console.log(data.responseJSON.message);
        }
    })

What is happening is jQuery is converting your object into a query param string and sending that. this looks like:

contactForm=%7B%22fistName%22%3A%22John%22%2C%...

Jackson is trying to interpret the query params as your request body which fails.

This can be confirmed by looking at the network tab in your browser and looking at the body of the request

Ad
source: stackoverflow.com
Ad