web-dev-qa-db-fra.com

Comment répondre avec un code d'état HTTP dans une classe Spring MVC @RestController @ResponseBody renvoyant un objet?

J'essaie d'avoir un @RestController qui prend un @PathVariable renvoie un objet spécifique au format JSON, accompagné du code d'état approprié. Jusqu'ici, le code retourne l'objet au format JSON, car il utilise la bibliothèque intégrée Spring 4 de Jackson par défaut.

Cependant, je ne sais pas comment le faire pour qu'il envoie un message à l'utilisateur en lui disant que nous voulons une variable api, puis des données JSON, puis un code d'erreur (ou un code de réussite, selon que tout s'est bien passé). Exemple de sortie serait:

Veuillez entrer la valeur de l’API en tant que paramètre (NOTE: ceci peut aussi être en JSON si nécessaire)

{"id": 2, "api": "3000105000" ...} (NOTE: ce sera l'objet de réponse JSON)

Code de statut 400 (OU code de statut approprié)


L'URL avec le paramètre ressemble à ceci

http://localhost:8080/gotech/api/v1/api/3000105000

Le code que j'ai jusqu'à présent:

@RestController
@RequestMapping(value = "/api/v1")
public class ClientFetchWellDataController {

    @Autowired
    private OngardWellService ongardWellService;

    @RequestMapping(value = "/wells/{apiValue}", method = RequestMethod.GET)
    @ResponseBody
    public OngardWell fetchWellData(@PathVariable String apiValue){
        try{
            OngardWell ongardWell = new OngardWell();
            ongardWell = ongardWellService.fetchOneByApi(apiValue);

            return ongardWell;
        }catch(Exception ex){
            String errorMessage;
            errorMessage = ex + " <== error";
            return null;
        }
    }
}
29
Cris

UNE @RestController n'est pas approprié pour cela. Si vous devez renvoyer différents types de réponses, utilisez un ResponseEntity<?> où vous pouvez définir explicitement le code de statut.

Le body du ResponseEntity sera traité de la même manière que la valeur de retour de n'importe quel @ResponseBody méthode annotée.

@RequestMapping(value = "/wells/{apiValue}", method = RequestMethod.GET)
public ResponseEntity<?> fetchWellData(@PathVariable String apiValue){
    try{
        OngardWell ongardWell = new OngardWell();
        ongardWell = ongardWellService.fetchOneByApi(apiValue);

        return new ResponseEntity<>(ongardWell, HttpStatus.OK);
    }catch(Exception ex){
        String errorMessage;
        errorMessage = ex + " <== error";
        return new ResponseEntity<>(errorMessage, HttpStatus.BAD_REQUEST);
    }
}

Notez que vous n'avez pas besoin de @ResponseBody sur un @RequestMapping méthode dans un @RestController classe annotée.

61

La manière idiomatique serait d'utiliser un gestionnaire d'exceptions au lieu de capturer l'exception dans votre méthode habituelle de traitement des demandes. Le type d'exception détermine le code de réponse. (403 pour une erreur de sécurité, 500 pour des exceptions inattendues sur la plate-forme, à votre guise)

@ExceptionHandler(MyApplicationException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public String handleAppException(MyApplicationException ex) {
  return ex.getMessage();
}

@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public String handleAppException(Exception ex) {
  return ex.getMessage();
}
31
Affe