1
votes

"Fin inattendue de l'entrée JSON" sur un contrôleur Ajax SpringMVC Void

J'ai une application SpringMVC / Thymeleaf où la gestion Ajax suivante fonctionne parfaitement si je renvoie un booléen . Cependant, dès que la méthode est void , j'obtiens l'erreur Fin inattendue de l'entrée JSON dans Firebug. Ceci est une requête POST.

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

JS

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

Si je supprime simplement @ResponseBody de la définition de méthode , Se plaint Thymeleaf, org.thymeleaf.exceptions.TemplateInputException: Erreur lors de la résolution du modèle [addOrUpdate], le modèle peut ne pas exister ou ne pas être accessible par l'un des résolveurs de modèles configurés

J'ai suivi le ResponseEntity exemple ici a>, mais cela n'a pas aidé - même erreur, JS entre dans la section Erreur avec une fin d'entrée inattendue.

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


0 commentaires

3 Réponses :


2
votes

Avec dataType: 'json' , vous indiquez à jQuery que vous attendez JSON comme réponse. Une réponse vide n'est pas un JSON valide, et le message d'erreur Fin inattendue de l'entrée JSON vous le dit exactement.

Si vous avez l'intention de ne rien renvoyer de la méthode du contrôleur addOrUpdate , supprimez l'annotation @ResponseBody , car il n'y a pas de corps de réponse, et tenez-vous-en au ResponseEntity mais utilisez plutôt HttpStatus.NO_CONTENT pour informer les clients dans votre réponse qu'il n'y a pas de contenu à attendre. Changez également votre dataType en quelque chose qui peut être vide, comme 'text' .


2 commentaires

J'ai tout fait comme vous l'avez dit, mais j'ai renvoyé HttpStatus.OK, car cela semblait plus informatif et cela fonctionne. Merci beaucoup!!


@geneb. "aucun contenu" est également un statut de réponse "réussi" - en fait, c'est le plus informatif car il transmet des informations supplémentaires qu'aucun contenu n'est attendu. Voir developer.mozilla.org/en-US/docs/Web / HTTP /…



0
votes

Comme le dit l'exception, le point de défaillance est l'entrée.
Vous devez envoyer une entrée au format json .

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


0 commentaires

0
votes

SOLUTION FINALE basée sur réponse de digitalbreed

Contrôleur

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

JS

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


0 commentaires