Tutoriel de base springboot2.x: filtre et intercepteur détaillés

Lors du développement du projet Web springboot, nous devons généralement demander l'interception du contenu de la demande et de la réponse, comme la journalisation des demandes, la vérification de l'UA, la vérification des autorisations de l'utilisateur, le filtrage de contenu illégal et d'autres fonctions. À ce stade, des filtres et des intercepteurs sont envoyés. utilisation.
Cet article vous explique comment springboot utilise des filtres et des intercepteurs et la différence entre les deux.

filtre

Les filtres de servlet peuvent intercepter dynamiquement les demandes et les réponses pour transformer ou utiliser les informations contenues dans la demande ou la réponse. Le filtre est une classe Java qui implémente l'interface javax.servlet.Filter. L'interface javax.servlet.Filter définit trois méthodes:

public interface Filter {
    default void init(FilterConfig filterConfig) throws ServletException {
    }
    void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;
    default void destroy() {
    }
}
Numéro de série Méthode et description
1 La
méthode doFilter termine l'opération de filtrage réelle. Lorsque le client demande une URL correspondant au paramètre de filtre, le conteneur Servlet appelle d'abord la méthode doFilter du filtre. Les utilisateurs de FilterChain accèdent aux filtres suivants.
2 Lorsque l'
application Web init est lancée, le serveur Web crée un objet d'instance de Filter, appelle sa méthode init, lit la configuration web.xml, termine la fonction d'initialisation de l'objet et prépare l'interception pour les demandes ultérieures des utilisateurs (objet filtre Il ne sera créé qu'une seule fois et la méthode init ne sera exécutée qu'une seule fois). Les développeurs peuvent obtenir l'objet FilterConfig représentant les informations de configuration de filtre actuelles via les paramètres de la méthode init.
3 Le
conteneur de servlet destroy appelle cette méthode avant de détruire l'instance de filtre, dans laquelle les ressources occupées par le filtre de servlet sont libérées.

SpringBoot utilise des filtres

Définit un filtre simple

@Slf4j
public class LogFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
         HttpServletRequest req=(HttpServletRequest)servletRequest;
         log.info(req.getRequestURI());
         filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {

    }
}

Utilisez FilterRegistrationBean pour enregistrer les filtres

@Configuration
public class LogFilterConfiguration {
    @Bean
    public FilterRegistrationBean registrationBean(){
        FilterRegistrationBean registrationBean=new FilterRegistrationBean();
        registrationBean.setFilter(new LogFilter());
        //匹配的过滤器
        registrationBean.addUrlPatterns("/*");
        //过滤器名称
        registrationBean.setName("logFilter");
        //过滤器顺序
        registrationBean.setOrder(1);
        return registrationBean;
    }
}

Utilisez les annotations Servlet3.0 pour définir des filtres

@WebFilter(urlPatterns = "/*",filterName = "authFiler")
@Slf4j
public class AuthFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
        log.info("进行权限校验.........");
        chain.doFilter(servletRequest,servletResponse);
    }

}

La différence entre les deux méthodes:

  1. L'annotation WebFilter ne spécifie pas l'attribut de l'ordre d'exécution. L'ordre d'exécution dépend du nom du filtre, qui est trié par ordre alphabétique inverse en fonction du nom de la classe Filter (notez qu'il ne s'agit pas du nom du filtre configuré)
  2. La priorité du filtre spécifié par @WebFilter est supérieure au filtre configuré par FilterRegistrationBean
  3. La méthode FilterRegistrationBean peut injecter des beans dans le conteneur IOC SpringBoot

Intercepteur

SpringBoot interceptor Interceptor Programmation orientée similaire dans la section et informer , via notre proxy dynamique pour une service()méthode d'ajout d' améliorations de la fonction de notification . Par exemple, avant que la méthode ne soit exécutée dans le processus d'initialisation , effectuée après la méthode de post-traitement . Idées d' intercepteur et AOPsimilaires, la différence est l'intercepteur uniquement sur Controllerla HTTPdemande d'interception.

public interface HandlerInterceptor {
    default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return true;
    }

    default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
    }

    default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
    }
}
Numéro de série Méthode et description
1 La
méthode preHandle est exécutée avant que le contrôleur ne reçoive la demande de traitement de la demande. La valeur de retour est booléenne. Lorsque la valeur de retour est true, les méthodes postHandle () et afterCompletion () sont exécutées; si elle renvoie false, l'exécution est interrompue.
2 postHandle est exécuté
après que le contrôleur a traité la demande et avant que ModelAndView ne la traite, et le résultat de la réponse peut être modifié.
3 afterCompletion
est exécuté une fois que DispatchServlet a traité cette demande, c'est-à-dire après la génération de ModelAndView.

Définir un intercepteur simple

@Slf4j
public class LogHandler implements HandlerInterceptor {
    private NamedThreadLocal<Long> startTimeThreadLocal = new NamedThreadLocal<>("StopWatch-StartTime");

    public LogHandler() {
        super();
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        long beginTime = System.currentTimeMillis();//1、开始时间      
        startTimeThreadLocal.set(beginTime);//线程绑定变量(该数据只有当前请求的线程可见)
        return true;//继续流程
    }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        long endTime = System.currentTimeMillis();
        long beginTime = startTimeThreadLocal.get();//得到线程绑定的局部变量(开始时间)  
        long consumeTime = endTime - beginTime;
        //3、消耗的时间         
        log.info(String.format("%s consume %d millis", request.getRequestURI(), consumeTime));
    }    
}

Enregistrer l'intercepteur

@Configuration
public class HandlerConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LogHandler());
    }
}

La différence entre filtre et intercepteur

Numéro de série la différence
1 Le filtre est une spécification de servlet, le domaine d'utilisation concerne les programmes Web, les intercepteurs ne sont pas limités aux programmes Web, mais peuvent également être utilisés dans les programmes Application et Swing
2 Le filtre est défini dans la spécification de servlet et pris en charge par le conteneur de servlet. L'intercepteur est dans le conteneur à ressort et soutenu par le cadre à ressort
3 L'intercepteur est un composant de Spring, qui peut utiliser des objets dans Spring, tels que des objets Service, des sources de données, la gestion des transactions et l'injection dans le conteneur via IOC, mais les filtres ne peuvent pas
4 Le filtre fonctionne avant et après le servlet, et l'intercepteur peut approfondir la méthode avant et après la levée de l'exception.
5 Les intercepteurs sont généralement préférés dans les projets Springboot

Mille miles commence par un seul pas. Ceci est le douzième article de la série de tutoriels SpringBoot. Tous les codes sources du projet peuvent être téléchargés sur mon GitHub .

Je suppose que tu aimes

Origine blog.csdn.net/github_35592621/article/details/108248940
conseillé
Classement