4
votes

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: java.io.PushbackInputStream@38220bcd; line: 1, column: 13]; nested exception is com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'contactForm': was expecting ('true', 'false' or 'null')
 at [Source: java.io.PushbackInputStream@38220bcd; 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
}
2

2 Answers

6
votes

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

0
votes

If you're manually set the ObjectMapper class in the controller as below.

    ObjectMapper obj = new ObjectMapper();
    obj.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    obj.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);

Or

  1. Add a dependency to javax.validation:validation-api in provided scope.
  2. Add the javax.validation.constraints.NotNull annotation to your field.

Hope this helps.

Since you have added SPRING has a tag, I would thought of setting that up from back-end stand-point.