Jin Jiu Yin 10 perdeu a primeira batalha, qual é a diferença entre filtro e interceptor, desta vez pode ser considerado como uma reunião

Este é um problema que encontrei durante uma entrevista há pouco tempo. Fiquei muito confuso na época. Embora os dois solteiros não estivessem completos, eles provavelmente sabiam que a solicitação poderia ser interceptada. Foi uma dor de cabeça compará-los.

Na verdade, fui aprender uma onda depois da entrevista antes, mas não a resumi a tempo naquela época, vou resumir agora, para não encontrar esses problemas no futuro e esquecer.

Para entender esse tipo de problema, a memorização mecânica pode ser útil na hora e quase será esquecida depois de um tempo. Para realmente lembrar, temos que fazer isso.

Uso de Filtro

Primeiro, para usar o Filtro, você deve implementar a interface javax.servlet.Filter:

public interface Filter {
	//web应用加载进容器,Filter对象创建之后,执行init方法初始化,用于加载资源,只执行一次。	
    public default void init(FilterConfig filterConfig) throws ServletException {}
	//每次请求或响应被拦截时执行,可执行多次。
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException;
	//web应用移除容器,服务器被正常关闭,则执行destroy方法,用于释放资源,只执行一次。
    public default void destroy() {}
}
  • Init e destroy são os métodos padrão e a classe de implementação não precisa ser implementada.
  • doFilter deve ser implementado, ou seja, como um filtro, doFilter deve ser definido.
  • O objeto FilterChain passado no método doFlilter é usado para chamar o próximo filtro.

Uso de interceptores

public interface HandlerInterceptor {
	//拦截handler的执行 --> 在HanlerMapping决定适合的handler之后,[在HandlerAdater调用handler之前执行。]
	default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {		return true;
	}	//拦截handler的执行 --> [在HandlerAdapter调用handler之后],在DispatcherServlet渲染视图之前执行
	default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			@Nullable ModelAndView modelAndView) throws Exception {	}	//视图渲染后调用,且只有preHandle结果为true,才会调用
	default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
			@Nullable Exception ex) throws Exception {	}}
//DispatcherServlet
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
    return; //遍历所有的interceptors,调用preHandle方法,只有返回true,才能进行下去
}
// 这里也就是处理Contrller
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
//视图渲染
applyDefaultViewName(processedRequest, mv);
//视图渲染之后调用
mappedHandler.applyPostHandle(processedRequest, response, mv);

Qual é a diferença entre um filtro e um interceptor?

1. O princípio de realização é diferente

  • A implementação do filtro é baseada na função de retorno de chamada
  • O interceptor é implementado com base no mecanismo de reflexão Java [proxy dinâmico].

Dois, o escopo de uso é diferente

  • O filtro é uma especificação de Servlet e precisa implementar a interface javax.servlet.Filter.O uso do Filtro precisa depender de contêineres como o Tomcat.
  • O interceptor é um componente Spring, definido no pacote org.springframework.web.servlet, gerenciado pelo contêiner Spring [com métodos de processamento de ciclo de vida mais ricos, refinado e capaz de usar recursos Spring] e não depende do Tomcat Espere pelo contêiner.

Três, o tempo de disparo é diferente

Este parágrafo pode ser encontrado na anotação da classe HandlerInterceptor, o tempo de disparo dos dois é diferente:

Jin Jiu Yin 10 perdeu a primeira batalha, qual é a diferença entre filtro e interceptor, desta vez

 

  • Filtro: Processe a solicitação antes ou depois de entrar no servlet.
  • Interceptor: A solicitação é processada antes e depois do manipulador [Controlador].

Jin Jiu Yin 10 perdeu a primeira batalha, qual é a diferença entre filtro e interceptor, desta vez

 

Quarto, a ordem de execução é diferente

Quando os filtros e interceptores são configurados:

MyFilter1 前
MyFilter2 前
MyInterceptor1 在Controller前执行
MyInterceptor2 在Controller前执行
controller方法执行...
MyInterceptor2 Controller之后,视图渲染之前
MyInterceptor1 Controller之后,视图渲染之前
MyInterceptor2 视图渲染完成之后执行
MyInterceptor1 视图渲染完成之后执行
MyFilter2 后
MyFilter1 后
  • Ordem dos filtros

Cada vez que o objeto da cadeia é passado para obter o efeito do retorno de chamada da interface final:

Jin Jiu Yin 10 perdeu a primeira batalha, qual é a diferença entre filtro e interceptor, desta vez

 

  • Ordem do interceptor

preHandle1 -> preHandle2 -> [Controlador] -> postHandle2 -> postHandle1 -> afterCompletion2 -> afterCompletion1 preHandle está na ordem de registro, e os dois últimos são opostos à ordem de registro.

  • Se o preHandle de um interceptor for falso, todos os interceptores subsequentes não serão executados.
  • Se o preHandle de um interceptor for verdadeiro, o triggerAfterCompletion desse interceptor será executado.
  • Somente se todos os interceptores preHandler forem verdadeiros, ou seja, forem executados normalmente, o postHandle será executado.
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
    HandlerInterceptor[] interceptors = getInterceptors();    if (!ObjectUtils.isEmpty(interceptors)) {
        for (int i = 0; i < interceptors.length; i++) {
            HandlerInterceptor interceptor = interceptors[i];            //一旦当前拦截器preHandle的返回值为false,那么从上一个可用的拦截器的afterCompletion开始
            if (!interceptor.preHandle(request, response, this.handler)) {
                triggerAfterCompletion(request, response, null);
                return false; //这里返回false意为 后续不进行下去了。
            }            this.interceptorIndex = i;//interceptorIndex初始化为-1,只有当前拦截器preHandle为true,才会赋值当前的i。
        }    }    return true;
}void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv)    throws Exception {    HandlerInterceptor[] interceptors = getInterceptors();    if (!ObjectUtils.isEmpty(interceptors)) {
        for (int i = interceptors.length - 1; i >= 0; i--) {
            HandlerInterceptor interceptor = interceptors[i];            interceptor.postHandle(request, response, this.handler, mv);
        }    }}void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex)    throws Exception {    HandlerInterceptor[] interceptors = getInterceptors();        for (int i = this.interceptorIndex; i >= 0; i--) 
}

Quinto, a sequência de execução do controle é diferente

Ambos usam a ordem de registro por padrão. Se você deseja controlar a ordem de execução, a forma é um pouco diferente:

  • Se você quiser forçar a mudança do filtro, você pode usar a anotação @Order.
  • Se o interceptor usa o método order ()
@Order(2)
@Component
public class MyFilter1 implements Filter {}
@Component
public class WebAdapter implements WebMvcConfigurer {
    @Autowired
    MyInterceptor1 myInterceptor1;    @Autowired
    MyInterceptor2 myInterceptor2;    @Override
    public void addInterceptors(InterceptorRegistry registry) {        registry.addInterceptor(myInterceptor1).addPathPatterns("/**").order(2);
        registry.addInterceptor(myInterceptor2).addPathPatterns("/**").order(1);
    }}

Resumindo

  • Em princípio, o filtro é baseado na implementação de retorno de chamada e o interceptor é baseado no proxy dinâmico.
  • Granularidade de controle: filtros e interceptores podem realizar a função de interceptação de solicitações, mas há uma grande diferença na granularidade de interceptação, e a granularidade do interceptor para controle de acesso é mais precisa.
  • Cenários de uso: os interceptores são frequentemente usados ​​para verificação de permissão, registros de log, etc., os filtros são usados ​​principalmente para filtrar parâmetros inválidos em solicitações e verificação de segurança.
  • Dependente do container: O filtro depende do container Servlet e está limitado à web, enquanto o interceptor depende do framework Spring e pode usar os recursos do framework Spring, não se limitando à web.
  • Tempo de acionamento: O filtro é executado antes e depois do servlet, e o interceptor é executado antes e depois do manipulador. Agora, a maioria dos aplicativos da web são baseados em Spring, e o interceptor é mais detalhado.

Se você acha que este artigo é útil para você, clique para apoiá-lo.

Você também pode acompanhar minha conta pública, há mais artigos técnicos sobre produtos secos e informações relacionadas sobre ela, todos aprendem e progridem juntos!

 

Acho que você gosta

Origin blog.csdn.net/weixin_50205273/article/details/108565814
Recomendado
Clasificación