tutorial básico do springboot2.x: filtro e interceptor detalhado

Durante o desenvolvimento do projeto da web springboot, geralmente precisamos solicitar o processamento de interceptação do conteúdo da solicitação e resposta, como registro de solicitação, verificação de UA, verificação de permissão do usuário, filtragem de conteúdo ilegal e outras funções. Nesse momento, filtros e interceptores são enviados. usar.
Este artigo explica como o springboot usa filtros e interceptores e a diferença entre os dois.

filtro

Os filtros de servlet podem interceptar solicitações e respostas dinamicamente para transformar ou usar as informações contidas na solicitação ou resposta. O filtro é uma classe Java que implementa a interface javax.servlet.Filter. A interface javax.servlet.Filter define três métodos:

public interface Filter {
    default void init(FilterConfig filterConfig) throws ServletException {
    }
    void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;
    default void destroy() {
    }
}
Número de série Método e Descrição
1 O
método doFilter conclui a operação de filtragem real.Quando o cliente solicita um URL que corresponda à configuração do filtro, o contêiner Servlet primeiro chama o método doFilter do filtro. Os usuários do FilterChain acessam os filtros subsequentes.
2 Quando o
aplicativo da web init é iniciado, o servidor da web irá criar um objeto de instância de Filter, chamar seu método init, ler a configuração web.xml, completar a função de inicialização do objeto e preparar para a interceptação de solicitações subsequentes do usuário (objeto de filtro Ele será criado apenas uma vez, e o método init será executado apenas uma vez). Os desenvolvedores podem obter o objeto FilterConfig que representa as informações de configuração do filtro atual por meio dos parâmetros do método init.
3 O
contêiner destroy Servlet chama esse método antes de destruir a instância do filtro, na qual os recursos ocupados pelo filtro do servlet são liberados.

SpringBoot usa filtros

Define um filtro simples

@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() {

    }
}

Use FilterRegistrationBean para registrar filtros

@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;
    }
}

Use anotações Servlet3.0 para definir filtros

@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);
    }

}

A diferença entre os dois métodos:

  1. A anotação WebFilter não especifica o atributo da ordem de execução. A ordem de execução depende do nome do Filtro, que é classificado em ordem alfabética reversa de acordo com o nome da classe do Filtro (observe que não é o nome do filtro configurado)
  2. A prioridade do filtro especificado por @WebFilter é maior do que o filtro configurado por FilterRegistrationBean
  3. O método FilterRegistrationBean pode injetar beans no contêiner IOC SpringBoot

Interceptor

SpringBoot interceptor Interceptor similar Oriented Programming na seção e informar , através de nosso proxy dinâmico para um service()método de adição de melhorias na função de notificação . Por exemplo, antes de o método ser executado no processo de inicialização , realizado após o método de execução de pós-processamento . Interceptor idéias e AOPsemelhantes, a diferença é o interceptor apenas Controllerno HTTPpedido de interceptação.

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 {
    }
}
Número de série Método e Descrição
1 O
método preHandle é executado antes que o controlador receba a solicitação para processar a solicitação. O valor de retorno é booleano. Quando o valor de retorno é verdadeiro, os métodos postHandle () e afterCompletion () são executados; se retornar falso, a execução é interrompida.
2 postHandle é executado
após o controlador processar a solicitação e antes de ModelAndView processá-la, e o resultado da resposta pode ser modificado.
3 afterCompletion
é executado após DispatchServlet processar essa solicitação, ou seja, após ModelAndView ser gerado.

Defina um interceptor simples

@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));
    }    
}

Registre o interceptor

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

A diferença entre filtro e interceptor

Número de série A diferença
1 O filtro é uma especificação de servlet, o escopo de uso são programas da web, os interceptores não estão limitados a programas da web, mas também podem ser usados ​​em aplicativos e programas Swing
2 O filtro é definido na especificação do servlet e suportado pelo contêiner do servlet. O interceptor está no contêiner Spring e é apoiado pela estrutura Spring
3 O interceptor é um componente do Spring, que pode usar objetos no Spring, como objetos de serviço, fontes de dados, gerenciamento de transações e injeção no contêiner por meio de IOC, mas os filtros não podem
4 O filtro funciona antes e depois do servlet, e o interceptor pode se aprofundar no método antes e depois que a exceção é lançada.
5 Interceptadores são geralmente preferidos em projetos springboot

Mil milhas começam com um único passo. Este é o décimo segundo artigo da série de tutoriais SpringBoot. Todos os códigos-fonte do projeto podem ser baixados em meu GitHub .

Acho que você gosta

Origin blog.csdn.net/github_35592621/article/details/108248940
Recomendado
Clasificación