1

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);
}       

3 Answers 3

2

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'.

Sign up to request clarification or add additional context in comments.

2 Comments

I did everything as you said but returned HttpStatus.OK, as that seemed more informative, and it's working. Thanks a lot!!
@geneb."no content" is a "successful" response status as well – in fact, it's the more informative one because it conveys additional information that no content is to be expected. See developer.mozilla.org/en-US/docs/Web/HTTP/…
0

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}
... 

Comments

0

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'
 });

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.