web-dev-qa-db-fra.com

Comment renvoyer un message d'erreur au printemps mvc @Controller

J'utilise des méthodes comme celle-ci 

@RequestMapping(method = RequestMethod.GET)
public ResponseEntity<UserWithPhoto> getUser(@RequestHeader(value="Access-key") String accessKey,
                                     @RequestHeader(value="Secret-key") String secretKey){
    try{
        return new ResponseEntity<UserWithPhoto>((UserWithPhoto)this.userService.chkCredentials(accessKey, secretKey, timestamp),
                new HttpHeaders(),
                HttpStatus.CREATED);
    }
    catch(ChekingCredentialsFailedException e){
        e.printStackTrace();
        return new ResponseEntity<UserWithPhoto>(null,new HttpHeaders(),HttpStatus.FORBIDDEN);
    }
}

Et je veux renvoyer un message texte quand une exception se produit, mais maintenant je retourne juste le statut et l’objet null. Est-il possible de faire?

29
user3378876

Comme Sotirios Delimanolis déjà souligné dans les commentaires, il y a deux options:

Retourne ResponseEntity avec un message d'erreur

Changez votre méthode comme ceci:

@RequestMapping(method = RequestMethod.GET)
public ResponseEntity getUser(@RequestHeader(value="Access-key") String accessKey,
                              @RequestHeader(value="Secret-key") String secretKey) {
    try {
        // see note 1
        return ResponseEntity
            .status(HttpStatus.CREATED)                 
            .body(this.userService.chkCredentials(accessKey, secretKey, timestamp));
    }
    catch(ChekingCredentialsFailedException e) {
        e.printStackTrace(); // see note 2
        return ResponseEntity
            .status(HttpStatus.FORBIDDEN)
            .body("Error Message");
    }
}

Note 1: Vous n'avez pas besoin d'utiliser le générateur ResponseEntity, mais cela aide à garder le code lisible. Cela aide également à garder en mémoire quelles données une réponse pour un code de statut HTTP spécifique doit inclure. Par exemple, une réponse avec le code d'état 201 doit contenir un lien vers la ressource nouvellement créée dans l'en-tête Location (voir Définitions des codes d'état ). C’est pourquoi Spring propose la méthode de construction très pratique ResponseEntity.created(URI)

Note 2: n'utilisez pas printStackTrace(), utilisez plutôt un enregistreur.

Fournir un @ExceptionHandler

Supprimez le bloc try-catch de votre méthode et laissez-le lever l'exception. Puis créez une autre méthode dans une classe annotée avec @ControllerAdvice comme ceci:

@ControllerAdvice
public class ExceptionHandlerAdvice {

    @ExceptionHandler(ChekingCredentialsFailedException.class)
    public ResponseEntity handleException(ChekingCredentialsFailedException e) {
        // log exception
        return ResponseEntity
                .status(HttpStatus.FORBIDDEN)
                .body("Error Message");
    }        
}

Notez que les méthodes annotées avec @ExceptionHandler peuvent avoir des signatures très souples. Voir la Javadoc pour plus de détails.

71
hzpz

Voici une alternative. Créez une exception générique qui prend un code d'état et un message. Créez ensuite un gestionnaire d'exceptions. Utilisez le gestionnaire d'exceptions pour extraire les informations en dehors de l'exception et revenir à l'appelant du service.

http://javaninja.net/2016/06/throwing-exceptions-messages-spring-mvc-controller/

public class ResourceException extends RuntimeException {

    private HttpStatus httpStatus = HttpStatus.INTERNAL_SERVER_ERROR;

    public HttpStatus getHttpStatus() {
        return httpStatus;
    }

    /**
     * Constructs a new runtime exception with the specified detail message.
     * The cause is not initialized, and may subsequently be initialized by a
     * call to {@link #initCause}.
     * @param message the detail message. The detail message is saved for later retrieval by the {@link #getMessage()}
     *                method.
     */
    public ResourceException(HttpStatus httpStatus, String message) {
        super(message);
        this.httpStatus = httpStatus;
    }
}

Utilisez ensuite un gestionnaire d'exceptions pour récupérer les informations et les renvoyer à l'appelant.

@ControllerAdvice
public class ExceptionHandlerAdvice { 

    @ExceptionHandler(ResourceException.class)
    public ResponseEntity handleException(ResourceException e) {
        // log exception 
        return ResponseEntity.status(e.getHttpStatus()).body(e.getMessage());
    }         
} 

Créez ensuite une exception lorsque vous en avez besoin.

throw new ResourceException(HttpStatus.NOT_FOUND, "We were unable to find the specified resource.");
9
Norris
return new ResponseEntity<>(GenericResponseBean.newGenericError("Error during the calling the service", -1L), HttpStatus.EXPECTATION_FAILED);
0
Sudabe-Neirizi