gene b.
gene b.

Reputation: 11996

"Unexpected end of JSON input" on a Void SpringMVC Ajax Controller

I have a SpringMVC/Thymeleaf applications where the following Ajax handling works perfectly fine if I return a boolean. However, as soon as the method is void, then I get the error Unexpected end of JSON input in Firebug. This is a POST request.

@ResponseBody
@PostMapping("/addOrUpdate")
public void /*boolean works!*/ addOrUpdate(@RequestBody String json) throws Exception {
    service.addOrUpdateUserRoles(json);
    /*boolean works - return true;*/
}

JS

 $.ajax({
        type : "post",
        dataType : 'json',
        contentType : 'text/plain', 
        url : 'addOrUpdate',  
        data : id 
 })
 .then(function() {
     //...
 })
 .fail(function(jqXHR, textStatus, errorThrown) {
     //...
 });

If I just remove @ResponseBody from the method definition, Thymeleaf complains, org.thymeleaf.exceptions.TemplateInputException: Error resolving template [addOrUpdate], template might not exist or might not be accessible by any of the configured Template Resolvers

I followed the ResponseEntity example here, but it didn't help -- same error, JS goes into the Error section with Unexpected End of Input.

@ResponseBody
@PostMapping("/addOrUpdate")
public ResponseEntity addOrUpdate(@RequestBody String json) throws Exception {
    service.addOrUpdate(json);
    return new ResponseEntity(HttpStatus.OK);
}       

Upvotes: 1

Views: 1229

Answers (3)

gene b.
gene b.

Reputation: 11996

FINAL SOLUTION based on digitalbreed's answer

Controller

@PostMapping("/addOrUpdate")
public ResponseEntity<String> addOrUpdate(@RequestBody String json) throws Exception {
    try {
        service.addOrUpdate(json);
        return new ResponseEntity<String>(HttpStatus.OK); // No exceptions
    }
    catch (Exception e) {
        log.error("Error", e);
        return new ResponseEntity<String>(HttpStatus.BAD_REQUEST); // This will enable JS to catch the Exception from Ajax
    }
}   

JS

 $.ajax({
        type : "post",
        dataType : 'text', // Returns a ResponseEntity, not JSON (Void method)
        contentType : 'text/plain', 
        url : 'addOrUpdate',  
        data : somedata
 })
 .then(function() {
      //...
 })
 .fail(function(jqXHR, textStatus, errorThrown) {
      //... - will come here for a ResponseEntity of 'Bad Request'
 });

Upvotes: 0

Ebrahim Pasbani
Ebrahim Pasbani

Reputation: 9406

As the exception says, the point of failure is input.
You need to send json format input.

$.ajax({
        type : "post",
        dataType : 'json',
        contentType : 'text/plain', 
        url : 'addOrUpdate',  
        data : {id: id}
... 

Upvotes: 0

digitalbreed
digitalbreed

Reputation: 4070

With dataType : 'json', you are telling jQuery that you're expecting JSON as a response. An empty response is no valid JSON, and the error message Unexpected end of JSON input is telling you exactly that.

If you intend not to return anything from the addOrUpdate controller method, remove the @ResponseBody annotation, as there is no response body, and stick to the ResponseEntity but use HttpStatus.NO_CONTENT instead to inform clients in your response that there's no content to be expected. Also, change your dataType to something that may be empty, like 'text'.

Upvotes: 2

Related Questions