Je souhaite utiliser un moyen générique pour gérer les codes d'erreur 5xx, disons spécifiquement le cas où la base de données est en panne dans toute mon application Spring. Je veux un joli json d'erreur au lieu d'une trace de pile.
Pour les contrôleurs, j'ai une @ControllerAdvice
classe pour les différentes exceptions et cela attrape également le cas où la base de données s'arrête au milieu de la demande. Mais ce n'est pas tout. Il se trouve que j'ai aussi une CorsFilter
extension personnalisée OncePerRequestFilter
et là, lorsque j'appelle, doFilter
je reçois le CannotGetJdbcConnectionException
et il ne sera pas géré par le @ControllerAdvice
. J'ai lu plusieurs choses en ligne qui m'ont rendu encore plus confus.
J'ai donc beaucoup de questions:
- Dois-je implémenter un filtre personnalisé? J'ai trouvé le
ExceptionTranslationFilter
mais cela ne gère queAuthenticationException
ouAccessDeniedException
. - J'ai pensé à implémenter la mienne
HandlerExceptionResolver
, mais cela m'a fait douter, je n'ai pas d'exception personnalisée à gérer, il doit y avoir un moyen plus évident que celui-ci. J'ai également essayé d'ajouter un try / catch et d'appeler une implémentation duHandlerExceptionResolver
(devrait être assez bon, mon exception n'a rien de spécial) mais cela ne renvoie rien dans la réponse, j'obtiens un statut 200 et un corps vide.
Y a-t-il un bon moyen de gérer cela? Merci
la source
Réponses:
Voici donc ce que j'ai fait:
J'ai lu les bases sur les filtres ici et j'ai compris que je devais créer un filtre personnalisé qui sera le premier dans la chaîne de filtres et j'aurai un essai pour attraper toutes les exceptions d'exécution qui pourraient s'y produire. Ensuite, je dois créer le json manuellement et le mettre dans la réponse.
Voici donc mon filtre personnalisé:
Et puis je l'ai ajouté dans le web.xml avant le
CorsFilter
. Et il fonctionne!la source
Je voulais fournir une solution basée sur la réponse de @kopelitsa . Les principales différences étant:
HandlerExceptionResolver
.Tout d'abord, vous devez vous assurer que vous disposez d'une classe qui gère les exceptions se produisant dans un RestController / Controller normal (une classe annotée avec
@RestControllerAdvice
ou@ControllerAdvice
et une ou plusieurs méthodes annotées avec@ExceptionHandler
). Cela gère vos exceptions se produisant dans un contrôleur. Voici un exemple utilisant RestControllerAdvice:Pour réutiliser ce comportement dans la chaîne de filtres Spring Security, vous devez définir un filtre et le raccorder à votre configuration de sécurité. Le filtre doit rediriger l'exception vers la gestion des exceptions définie ci-dessus. Voici un exemple:
Le filtre créé doit ensuite être ajouté à SecurityConfiguration. Vous devez le raccorder à la chaîne très tôt, car toutes les exceptions du filtre précédent ne seront pas interceptées. Dans mon cas, il était raisonnable de l'ajouter avant le
LogoutFilter
. Voir la chaîne de filtres par défaut et son ordre dans la documentation officielle . Voici un exemple:la source
Je rencontre ce problème moi-même et j'ai effectué les étapes ci-dessous pour réutiliser mon
ExceptionController
annoté@ControllerAdvise
pour leExceptions
lancer dans un filtre enregistré.Il y a évidemment de nombreuses façons de gérer l'exception mais, dans mon cas, je voulais que l'exception soit gérée par mon
ExceptionController
parce que je suis têtu et aussi parce que je ne veux pas copier / coller le même code (c'est-à-dire que j'ai du traitement / journalisation code dansExceptionController
). Je voudrais retourner la belleJSON
réponse, tout comme le reste des exceptions lancées pas d'un filtre.Quoi qu'il en soit, j'ai réussi à utiliser mon
ExceptionHandler
et j'ai dû faire un peu plus comme indiqué ci-dessous dans les étapes:Pas
@ControllerAdvise
ie MyExceptionControllerExemple de code
Et maintenant, l'exemple de Spring Controller qui gère
Exception
les cas normaux (c'est-à-dire les exceptions qui ne sont généralement pas levées au niveau du filtre, celle que nous voulons utiliser pour les exceptions levées dans un filtre)Partager la solution avec ceux qui souhaitent utiliser
ExceptionController
pourExceptions
jeté dans un filtre.la source
@Component
classe et l'utiliser dans le filtre et dans le controlle.answer
c'est l'un des moyens! Je n'ai pas prétendu que c'était la meilleure façon. Merci d'avoir partagé votre inquiétude @psv Je suis sûr que la communauté apprécierait la solution que vous avez en tête :)Alors, voici ce que j'ai fait sur la base d'un amalgame des réponses ci-dessus ... Nous avions déjà un
GlobalExceptionHandler
annoté avec@ControllerAdvice
et je voulais aussi trouver un moyen de réutiliser ce code pour gérer les exceptions qui proviennent des filtres.La solution la plus simple que j'ai pu trouver était de laisser le gestionnaire d'exceptions seul et d'implémenter un contrôleur d'erreur comme suit:
Ainsi, toutes les erreurs causées par des exceptions passent d'abord par le
ErrorController
et sont redirigées vers le gestionnaire d'exceptions en les renvoyant à partir d'un@Controller
contexte, tandis que toutes les autres erreurs (non causées directement par une exception) passent par leErrorController
sans modification.Des raisons pour lesquelles c'est en fait une mauvaise idée?
la source
@Override public String getErrorPath() { return null; }
Si vous souhaitez une méthode générique, vous pouvez définir une page d'erreur dans web.xml:
Et ajoutez le mappage dans Spring MVC:
la source
C'est ma solution en remplaçant le gestionnaire Spring Boot / error par défaut
la source
Juste pour compléter les autres bonnes réponses fournies, car je voulais trop récemment un seul composant de gestion des erreurs / exceptions dans une simple application SpringBoot contenant des filtres pouvant générer des exceptions, avec d'autres exceptions potentiellement générées par les méthodes du contrôleur.
Heureusement, il semble que rien ne vous empêche de combiner les conseils de votre contrôleur avec un remplacement du gestionnaire d'erreurs par défaut de Spring pour fournir des charges utiles de réponse cohérentes, vous permettre de partager la logique, d'inspecter les exceptions des filtres, d'intercepter les exceptions lancées par un service spécifique, etc.
Par exemple
la source
Lorsque vous souhaitez tester un état d'application et en cas de problème de retour d'erreur HTTP, je vous suggère un filtre. Le filtre ci-dessous gère toutes les requêtes HTTP. La solution la plus courte dans Spring Boot avec un filtre javax.
Dans la mise en œuvre peut être diverses conditions. Dans mon cas, l'applicationManager teste si l'application est prête.
la source
Après avoir lu les différentes méthodes suggérées dans les réponses ci-dessus, j'ai décidé de gérer les exceptions d'authentification en utilisant un filtre personnalisé. J'ai pu gérer l'état et les codes de réponse à l'aide d'une classe de réponse d'erreur en utilisant la méthode suivante.
J'ai créé un filtre personnalisé et modifié ma configuration de sécurité en utilisant la méthode addFilterAfter et ajouté après la classe CorsFilter.
Classe SecurityConfig
Classe ErrorResponse
la source
Vous pouvez utiliser la méthode suivante dans le bloc catch:
Notez que vous pouvez utiliser n'importe quel code HttpStatus et un message personnalisé.
la source
C'est étrange parce que @ControllerAdvice devrait fonctionner, attrapez-vous la bonne exception?
Essayez également d'attraper cette exception dans CorsFilter et envoyez une erreur 500, quelque chose comme ça
la source
Filter
peut ne pas être rattrapé@ControllerAdvice
car in peut ne pas atteindreDispatcherServlet
.Vous n'avez pas besoin de créer un filtre personnalisé pour cela. Nous avons résolu ce problème en créant des exceptions personnalisées qui étendent ServletException (qui est levée à partir de la méthode doFilter, indiquée dans la déclaration). Ceux-ci sont ensuite capturés et gérés par notre gestionnaire d'erreurs global.
modifier: grammaire
la source