web-dev-qa-db-fra.com

Quels sont les avantages de @ControllerAdvice par rapport à @ExceptionHandler ou HandlerExceptionResolver pour la gestion des exceptions?

Spring 3.2 a introduit l'annotation @ControllerAdvice pour la gestion des exceptions dans une application Spring MVC. Mais avant cette version, Spring avait @ExceptionHandler ou HandlerExceptionResolver pour gérer les exceptions dans une application Spring MVC. Dans ce cas, pourquoi la Spring 3.2 a-t-elle introduit l'annotation @ControllerAdvice pour la gestion des exceptions? Je crois fermement que Spring 3.2 a introduit l'annotation @ControllerAdvice pour remédier aux limitations de @ExceptionHandler ou HandlerExceptionResolver ou pour rendre le traitement des exceptions plus fort .

Quelqu'un peut-il expliquer les avantages de @ControllerAdvice par rapport à @ExceptionHandler ou HandlerExceptionResolver pour la gestion des exceptions?

13
Rajorshi Roy

@ExceptionHandler

@ExceptionHandler fonctionne au niveau du contrôleur et il n'est actif que pour ce contrôleur particulier} pas globalement pour l'ensemble de l'application.

HandlerExceptionResolver

Cela résoudra toute exception levée par l'application. Il est utilisé pour résoudre les exceptions Spring standard en codes d'état HTTP correspondants. Il n'a pas de contrôle sur le corps de la réponse, cela signifie il ne définit rien dans le corps de la réponse}. Il mappe le code d'état sur la réponse mais le le corps est nul.

@ControllerAdvice

@ControllerAdvice utilisé pour le traitement des erreurs globales dans l'application Spring MVC. Il contrôle également entièrement le corps de la réponse et le code d'état.

23
UUIUI

Un @ExceptionHandler est local sur un contrôleur: seules les exceptions de ce contrôleur sont routées vers son @ExceptionHandler

Mais un @ControllerAdvice est global: vous pouvez avoir un moyen centralisé de gérer les exceptions, les liaisons, etc. Il s’applique à tous les contrôleurs définis.

11
Jérémie B

Voici la différence: Si je dois configurer le code de traitement des exceptions, je dois utiliser une annotation @ExceptionHandler dans mon projet, qui peut être utilisée de deux manières différentes: 1) Pour utiliser le annotation et gérer l’exception dans le même contrôleur localement dans chaque classe de contrôleur. pour, par exemple:

@RestController
public class WSExposingController{

@GetMapping("/getAllDetails/{/id}")
public UserDetails myMethod(@PathVariable int id){
UserDetails user = UserDetailsService.getUser(id);
return user;
}

//To handle the exceptions which are resulting from this controller, I can declare an exceptionHandler specifically in the same class

@ExceptionHandler(Exception.class)
public ResponseEntity handlerSameControllerExceptions(){
return new ResponseEntity(null,HttpStatus.INTERNAL_SERVER_ERROR);

}

}

2) Si je crée une nouvelle classe qui étend ResponseEntityExceptionHandler (classe SpringBoot) et si je l'ANNOTATE AVEC @ControllerAdvice, cette classe devient Globalexceptionhandler, ce qui signifie que toute exception qui Il en résulte que toute classe de contrôleur peut être gérée ici. Et il peut être présent dans n’importe quel paquet Du même projet.

@RestController
@ControllerAdvice
public class GlobalJavaExceptionHandler extends ResponseEntityExceptionHandler{

    @ExceptionHandler(Exception.class)
    public ResponseEntity handleDiffControllerExceptions(){
        return new ResponseEntity(null,HttpStatus.INTERNAL_SERVER_ERROR);
    }

Si les deux sont présents dans le code, la locale avec la priorité sur la globale. Idéalement, la deuxième option est la meilleure car nous n'avons pas besoin d'ajouter le code dans chaque classe de contrôleur et cette classe avec @ControllerAdvice. peut constituer une solution unique pour toutes les exceptions dues au code commençant du contrôleur au dao sur toute la longueur du code.

3
Mohammed Amen

@ExceptionHandler peut être utilisé au niveau local ou global. Au niveau local, vous utiliseriez cette annotation dans le contrôleur lui-même pour gérer les exceptions au sein de ce contrôleur uniquement. Toute erreur renvoyée par ce contrôleur serait interceptée par ce @ExceptionHandler. Mais cela signifierait que s'il existait une exception similaire dans un autre contrôleur, vous auriez à réécrire localement le code correspondant dans ce contrôleur. 

Afin d'éviter de répéter ce style de gestion des exceptions par contrôleur, nous pouvons écrire @ExceptionHanlder au niveau global à l'aide d'une autre annotation appelée @ControllerAdvice.

@ControllerAdvice n'est pas spécifique à la gestion des exceptions, il est également utilisé pour gérer les liaisons de propriété, de validation ou de formatage au niveau global. @ ControllerAdvice dans le contexte de la gestion des exceptions n'est qu'une autre façon de gérer des exceptions à un niveau global. niveau en utilisant l'annotation @Exceptionhandler.

Nous en arrivons maintenant à HandlerExceptionResolver - il s’agit d’une interface de niveau inférieur. Spring fournit 2 implémentations de ceci:

  • ResponseStatusExceptionResolver: ceci prend en charge l'annotation @ResponseStatus
  • ExceptionHandlerExceptionResolver: Ceci prend en charge l'annotation @ExceptionHandler.

Exemple: lorsque vous souhaitez gérer les exceptions et choisir une stratégie de gestion des exceptions, vous devez choisir entre l'utilisation d'une gestion des exceptions locale ou globale via les annotations. Comment vous devez fournir les codes d’état HTTP, comment l’envelopper dans l’entité @Response, etc., comment vous souhaitez rediriger les pages du gestionnaire, transférer les données via des attributs flash ou obtenir des paramètres, etc. Ou peut-être sauter les annotations et utilisez SimpleMappingExceptionResolver et commencez à mapper les exceptions spécifiques aux URL de la page du gestionnaire d'erreurs

Ici, nous n’envisageons pas le niveau inférieur sous-jacent HandlerExceptionResolver à ce stade car nous nous occupons de sa mise en œuvre à un niveau supérieur et nous construisons la stratégie sur la base de ces options. 

Avec le contexte ci-dessus pour répondre à votre requête - @ControllerAdvice n'a pas été introduit pour la gestion des exceptions, c'est un mécanisme que vous pouvez utiliser pour gérer les exceptions de manière globale à l'aide de @ExceptionHandler. HandlerExceptionResolver est une interface dont l'implémentation permet de prendre en charge les annotations @ResponseStatus et @Exceptionhandler. Sauf si vous souhaitez gérer les exceptions liées au système MVC, car la structure Spring ne fournit aucune gestion des exceptions appropriée. Donc, si vous avez besoin de résoudre des problèmes liés à un @Requestmapping incorrect, etc., qui ne seraient pas détectés par un contrôleur car il ne l'atteindrait même pas à la 1ère place, une implémentation de HandlerExceptionResolver serait utile.

1
Chetan Handa