![translation](https://cdn.durumis.com/common/trans.png)
Ceci est un post traduit par IA.
[Spring] Qu'est-ce que Filter, Interceptor et Argument Resolver ?
- Langue de rédaction : Coréen
- •
-
Pays de référence : Tous les pays
- •
- Technologies de l'information
Choisir la langue
Texte résumé par l'IA durumis
- Un filtre est une fonctionnalité standard J2EE qui permet de traiter des tâches supplémentaires pour toutes les requêtes correspondant à un modèle d'URL avant ou après qu'elles soient transmises au servlet de dispatch. Il s'exécute dans un conteneur Web. Un intercepteur est une technologie fournie par Spring qui permet de référencer ou de modifier les requêtes et les réponses avant et après que le servlet de dispatch appelle un contrôleur. Il s'exécute dans le contexte Spring.
- Un Argument Resolver peut indirectement créer l'objet souhaité à partir des valeurs reçues dans une requête lorsqu'elle arrive à un contrôleur.
- Les différences entre Filter et Interceptor résident dans le fait qu'ils s'exécutent dans le conteneur Web ou dans le conteneur Spring, qu'ils traitent les requêtes par rapport au servlet de dispatch ou au contrôleur. Argument Resolver s'exécute après l'intercepteur et renvoie un objet spécifique.
Qu'est-ce qu'un filtre ?
Un filtre est une fonctionnalité standard J2EE qui permet de traiter des tâches supplémentaires pour toutes les requêtes correspondant à un modèle d'URL avant ou après qu'elles soient transmises au servlet de réexpédition. En d'autres termes, il est géré par le conteneur Web (comme Tomcat) plutôt que par le conteneur Spring, ce qui signifie qu'il traite les requêtes avant qu'elles n'atteignent le servlet de réexpédition.
Implémentation d'un filtre
Pour ajouter un filtre, vous devez implémenter l'interface Filter de javax.servlet, qui comprend les trois méthodes suivantes.
- Méthode init
- Cette méthode initialise l'objet filtre et l'ajoute au service. Le conteneur Web appelle une fois la méthode init pour initialiser l'objet filtre, après quoi les requêtes suivantes sont traitées par la méthode doFilter().
- Méthode doFilter
- Cette méthode est exécutée par le conteneur Web avant que toute requête HTTP correspondant au modèle d'URL ne soit transmise au servlet de réexpédition, et elle est également exécutée par le conteneur Web avant que le servlet de réexpédition n'envoie une réponse HTTP au client.
Le paramètre de doFilter() est FilterChain, qui transmet la requête à la prochaine destination via doFilter() de FilterChain. Vous pouvez insérer le processus de traitement dont vous avez besoin avant/après chain.doFilter() pour effectuer le traitement souhaité.
- Cette méthode est exécutée par le conteneur Web avant que toute requête HTTP correspondant au modèle d'URL ne soit transmise au servlet de réexpédition, et elle est également exécutée par le conteneur Web avant que le servlet de réexpédition n'envoie une réponse HTTP au client.
- Méthode destory
- Cette méthode supprime l'objet filtre du service et renvoie les ressources utilisées. Elle est appelée une fois par le conteneur Web, après quoi elle n'est plus traitée par doFilter().
Exemple de code - Spécification Servlet
@WebFilter("/*")
public class dolphagoFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
// Prétraitement ici
request.setCharacterEncoding("UTF-8");
System.out.println("Avant doFilter()....");
filterChain.doFilter(request, response);
// Post-traitement ici
System.out.println("Après doFilter()....");
}
@Override
public void destroy() { }
Exemple de code - @Component
@Order(1)
@Component
public class CustomFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException { }
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
chain.doFilter(request, response);
}
@Override
public void destroy() { }
- @Component : vous permet d'enregistrer Filter en tant que bean Spring.
- @Order : vous permet de définir l'ordre des filtres s'il y en a plusieurs.
- Enregistrez le filtre correspondant à la spécification du servlet en tant que bean Spring de cette manière, vous pouvez utiliser d'autres beans correspondant à la spécification Spring.
Exemple de code - @Configuration
@Configuration
public class CustomRegistrationBean {
@Bean
public FilterRegistrationBean customFilterBean() {
FilterRegistrationBean registration = new FilterRegistrationBean<>();
registration.setFilter(new CustomFilter());
registration.setOrder(1);
registration.addUrlPatterns("/api/*");
return registration;
}
Si vous souhaitez que le filtre ne fonctionne que pour un URI spécifique, vous pouvez utiliser FilterRegistrationBean pour enregistrer le filtre en tant que bean Spring.
Utilisations des filtres
Les filtres sont principalement responsables de la validation et du traitement des paramètres de la requête elle-même.
- Tâches communes liées à la sécurité
- Les filtres fonctionnent dans le conteneur Web, vous pouvez donc effectuer des vérifications de sécurité (comme la protection contre les XSS, la défense CSRF) pour bloquer les requêtes invalides. En empêchant les requêtes d'atteindre le conteneur Spring, vous pouvez améliorer la sécurité.
- Journalisation de toutes les requêtes
- Compression d'images/données et encodage de chaînes
- Les filtres ont implémenté des fonctionnalités utilisées dans l'ensemble de l'application Web, telles que la compression d'images ou de données, et l'encodage de chaînes.
- Personnalisation de ServletRequest
- HttpServletRequest ne peut lire le contenu du corps qu'une seule fois. Par conséquent, les filtres ou les intercepteurs ne peuvent pas lire le corps. Vous pouvez créer un ServletRequest personnalisé pour journaliser le corps.
Intercepteur
Qu'est-ce qu'un intercepteur ?
Contrairement aux filtres, qui sont une spécification standard J2EE, les intercepteurs sont une technologie fournie par Spring, qui permet de référencer ou de modifier les requêtes et les réponses avant et après que le servlet de réexpédition appelle le contrôleur. En d'autres termes, contrairement aux filtres qui fonctionnent dans le conteneur Web, les intercepteurs fonctionnent dans le contexte Spring.
Le servlet de réexpédition demande au mappage de gestionnaire de trouver le contrôleur approprié, ce qui renvoie une chaîne d'exécution (HandlerExecutionChain). Par conséquent, si cette chaîne d'exécution contient au moins un intercepteur enregistré, les intercepteurs sont exécutés séquentiellement avant l'exécution du contrôleur, et si aucun intercepteur n'est trouvé, le contrôleur est exécuté directement.
Implémentation d'un intercepteur
Pour ajouter un intercepteur, vous devez implémenter l'interface org.springframework.web.servlet.HandlerInterceptor, qui comprend les trois méthodes suivantes.
- Méthode preHandle
- La méthode preHandle est exécutée avant l'appel du contrôleur. Par conséquent, elle peut être utilisée pour effectuer des tâches de prétraitement avant le contrôleur, pour modifier ou ajouter des informations de requête.
- Le troisième paramètre de la méthode preHandle, le paramètre handler, est un objet qui abstrait les informations de la méthode annotée avec @RequestMapping.
- Le type de retour de la méthode preHandle est boolean. Si la valeur de retour est true, le processus passe à l'étape suivante, mais si la valeur de retour est false, le travail est interrompu, et les tâches ultérieures (le prochain intercepteur ou le contrôleur) ne sont pas exécutées.
- Méthode postHandle
- La méthode postHandle est exécutée après l'appel du contrôleur. Par conséquent, elle peut être utilisée pour effectuer des tâches de post-traitement après le contrôleur.
- Méthode afterCompletion
- Comme son nom l'indique, la méthode afterCompletion est exécutée après que toutes les tâches ont été terminées, y compris la création du résultat final par toutes les vues.
Exemple de code
@Component
public class CustomInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}
}
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new CustomInterceptor());
registry.addInterceptor(new LoggingInterceptor());
}
- Enregistrer l'intercepteur créé en tant que bean.
- Enregistrer l'intercepteur créé dans la méthode addInterceptors() de l'interface WebMvcConfigurer.
- Les intercepteurs fonctionnent dans l'ordre dans lequel ils sont enregistrés dans InterceptorRegistry.
Utilisations des intercepteurs
Les intercepteurs sont principalement responsables du traitement de la cohérence des informations de requête à l'aide de la logique du service.
- Tâches communes telles que l'authentification/l'autorisation
- Par exemple, vous pouvez effectuer des tâches liées à la requête client, telles que l'authentification ou l'autorisation, avant qu'elles ne soient transmises au contrôleur.
- Journalisation des appels API
- Vous pouvez enregistrer des informations sur le client via les objets HttpServletRequest et HttpServletResponse transmis.
- Traitement des données transmises au contrôleur
- Vous pouvez traiter les objets HttpServletRequest et HttpServletResponse transmis et les transmettre au contrôleur.
- Simulation d'AOP
- Vous pouvez obtenir des informations supplémentaires, telles que la signature de la méthode qui sera exécutée, à partir de HandlerMethod, le troisième paramètre de la méthode preHandle(), pour déterminer si la logique doit être exécutée.
Filtre vs intercepteur
- Les filtres sont exécutés dans le contexte Web, tandis que les intercepteurs sont exécutés dans le contexte Spring, ce qui signifie qu'ils ont des moments d'exécution différents.
- Les filtres peuvent gérer les actions avant et après le servlet de réexpédition, tandis que les intercepteurs peuvent gérer les actions avant et après le contrôleur.
- Les filtres sont mieux utilisés pour les tâches qui doivent être traitées globalement indépendamment de Spring, pour valider les paramètres d'entrée eux-mêmes, ou pour utiliser ServletRequest au lieu de HttpServletRequest.
- Les intercepteurs sont mieux utilisés pour les tâches qui doivent être traitées globalement dans le cadre de Spring, ou lorsque vous devez mélanger la logique du service.
- Les intercepteurs peuvent utiliser @ControllerAdvice et @ExceptionHandler pour gérer les exceptions, mais les filtres ne peuvent pas le faire.
- Les filtres gèrent généralement les exceptions qui se produisent à ce moment-là en enveloppant la méthode doFilter() dans un bloc try~catch.
Résolveur d'arguments
Qu'est-ce qu'un résolveur d'arguments ?
Un résolveur d'arguments peut indirectement créer l'objet souhaité à partir des valeurs transmises dans la requête lorsqu'une requête est transmise au contrôleur.
Utilisations des résolveurs d'arguments
Par exemple, supposons qu'une requête est transmise avec un jeton JWT. Nous devons valider que le jeton est un jeton valide, puis extraire l'ID stocké dans le jeton et le convertir en objet utilisateur connecté.
Dans ce cas, si vous n'utilisez pas de résolveur d'arguments, vous devez implémenter le processus de validation du jeton et de conversion en objet utilisateur connecté dans tous les contrôleurs. Cela entraîne un code dupliqué dans les contrôleurs qui nécessitent la validation de l'utilisateur, et augmente les responsabilités du contrôleur. Ce problème peut être résolu par les résolveurs d'arguments.
Implémentation d'un résolveur d'arguments
Vous pouvez utiliser ArgumentResolver en implémentant HandlerMethodArgumentResolver. Cette interface indique que les deux méthodes suivantes doivent être implémentées.
boolean supportsParameter(MethodParameter parameter);
@Nullable
- Méthode supportsParameter
- Ajoutez une annotation spécifique au paramètre de la méthode pour laquelle vous souhaitez que le résolveur d'arguments s'exécute. La méthode supportsParameter() vérifie si le paramètre de la méthode demandée contient l'annotation souhaitée, et retourne true si elle contient l'annotation souhaitée.
- Méthode resolveArgument
- Si la méthode supportsParameter() retourne true, c'est-à-dire s'il existe une méthode avec l'annotation spécifique, cette méthode retourne le paramètre lié sous la forme souhaitée.
Voici une implémentation de contrôleur lorsque vous utilisez ArgumentResolver.
@GetMapping("/me")
public ResponseEntity findMemberOfMine(@AuthenticationPrincipal LoginMember loginMember) {
MemberResponse memberResponse = memberService.findMember(loginMember.getId());
return ResponseEntity.ok().body(memberResponse);
Différences entre les résolveurs d'arguments et les intercepteurs
- Les résolveurs d'arguments fonctionnent après les intercepteurs, et retournent l'objet souhaité à partir des valeurs transmises dans la requête lorsqu'une requête est transmise au contrôleur.
- En revanche, les intercepteurs interceptent la requête avant que le contrôleur ne soit réellement exécuté, et ne peuvent pas retourner d'objet spécifique. Ils n'ont que des types de retour boolean ou void.
Source
- https://mangkyu.tistory.com/173
- https://junhyunny.github.io/spring-boot/filter-interceptor-and-aop/
- https://supawer0728.github.io/2018/04/04/spring-filter-interceptor/
- https://tecoble.techcourse.co.kr/post/2021-05-24-spring-interceptor/
- https://baeldung-cn.com/spring-mvc-handlerinterceptor-vs-filter
- https://www.baeldung.com/spring-boot-add-filter
Questions d'entretien prévues et réponses
Qu'est-ce qu'un filtre ?
Un filtre est une fonctionnalité qui permet de traiter des tâches supplémentaires pour toutes les requêtes correspondant à un modèle d'URL avant ou après qu'elles soient transmises au servlet de réexpédition, et il fonctionne au niveau du conteneur de servlet.
Quand utiliser un filtre ?
Les filtres peuvent être utilisés pour traiter des tâches qui doivent être traitées globalement indépendamment de Spring. Ou, il est utilisé pour valider les paramètres de la requête elle-même.
Par exemple, il traite des tâches communes liées à la sécurité, la journalisation de toutes les requêtes, la compression d'images/données et l'encodage de chaînes, et la personnalisation de ServletRequest.
Qu'est-ce qu'un intercepteur ?
Un intercepteur est une fonctionnalité qui permet de référencer ou de modifier les requêtes et les réponses avant et après que le servlet de réexpédition appelle le contrôleur, c'est-à-dire qu'il fonctionne au niveau du conteneur Spring.
Quand utiliser un intercepteur ?
Les intercepteurs peuvent être utilisés pour traiter des tâches qui doivent être traitées globalement dans le cadre de Spring, ou pour valider les paramètres de la requête en appelant la logique du service.
Par exemple, il traite des tâches communes telles que l'authentification/l'autorisation, la journalisation des appels API, le traitement des données transmises au contrôleur.
Différences entre un filtre et un intercepteur ?
Les filtres sont exécutés au niveau du conteneur de servlet, tandis que les intercepteurs sont exécutés au niveau du conteneur Spring.
Les filtres peuvent gérer les actions avant et après le servlet de réexpédition, tandis que les intercepteurs peuvent gérer les actions avant et après le contrôleur.
Par conséquent, les filtres sont mieux utilisés pour les tâches qui doivent être traitées globalement indépendamment de Spring, et les intercepteurs sont mieux utilisés pour les tâches qui doivent être traitées globalement dans le cadre de Spring.
Qu'est-ce qu'un résolveur d'arguments ?
Un résolveur d'arguments est une fonctionnalité qui crée indirectement l'objet souhaité à partir des valeurs transmises dans la requête lorsqu'une requête est transmise au contrôleur.
Quand utiliser un résolveur d'arguments ?
Il peut être utilisé lorsque vous recevez une requête avec un jeton JWT, et lorsque vous devez valider si le jeton est un jeton valide, puis extraire l'ID stocké dans le jeton et le convertir en un objet LoginMember.
Différences entre un intercepteur et un résolveur d'arguments ?
Un résolveur d'arguments retourne l'objet souhaité à partir des valeurs transmises dans la requête lorsqu'une requête est transmise au contrôleur. En revanche, les intercepteurs ne peuvent pas retourner d'objet comme celui-ci, et le résolveur d'arguments est exécuté après l'exécution de l'intercepteur.