Diferenças entre Filtros e Interceptadores
Os filtros e interceptadores possuem diferenças fundamentais:
- Interceptadores são baseados em reflexão Java, enquanto filtros utilizam callbacks funcionais
- Interceptadores não dependem do container servlet, já filtros são dependentes
- Interceptadores atuam apenas em requisições de ação, enquanto filtros podem processar quase todos os tipos de requisição
- Interceptadores podem acessar contexto de ação, valores e objetos da pilha, capacidade não disponível para filtros
- Durante o ciclo de vida da ação, interceptadores podem ser invocadso múltiplas vezes, enquanto filtros são chamados apenas uma vez durante a inicialização
- Interceptadores podem obter beans do container IOC, permitindo injeção de serviços e chamada de lógica de negócio
Execução de Filtros
Os filtros são executados antes das requisições chegarem à camada controller. O ciclo de vida de um filtro compreende três etapas:
- init: O objeto filter é criado uma única vez e o método init é executado apenas uma vez
- doFilter: Método principal onde a lógica de negócio é implemetnada, podendo ser chamado repetidamente
- destroy: Executado automaticamente quando o filtro é destruído (fechamento do programa ou destruição ativa)
Configuração de Filtros
A anotação @Order(1) define a ordem de execução quando múltiplos filtros estão presentes. Sem especificação, a ordenação padrão segue a ordem alfabética dos nomes dos filtros.
Observação importante: A anotação @ServletComponentScan na classe de aplicação Spring Boot permite o registro automático de Servlet, Filter e Listener através das anotações @WebServlet, @WebFilter e @WebListener, sem necessidade de código adicional.
Implementação Prática
Dependências Necessárias
Adicione a dependência spring-boot-starter-web no arquivo pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Criação do Filtro
O parâmetro urlPatterns define os padrões de URL que serão filtrados. No exemplo abaixo, o filtro atua sobre todos os métodos do controller com mapeamento @RequestMapping("/funcionario/dados"). Para aplicar a todas as requisições, utilize urlPatterns = "/*".
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebFilter(filterName = "filtroPrincipal", urlPatterns = "/funcionario/dados/*")
public class FiltroCustomizado implements Filter {
@Override
public void init(FilterConfig configFiltro) throws ServletException {
System.out.println("FiltroCustomizado inicializado com sucesso...");
}
@Override
public void doFilter(ServletRequest requisicao, ServletResponse resposta, FilterChain cadeia)
throws IOException, ServletException {
System.out.println("Processando filtro...");
HttpServletRequest reqHttp = (HttpServletRequest) requisicao;
HttpServletResponse resHttp = (HttpServletResponse) resposta;
String caminhoServlet = reqHttp.getServletPath();
System.out.println("Caminho da requisição: " + caminhoServlet);
if (caminhoServlet.equals("/funcionario/dados/upload")) {
String novoCaminho = "/funcionario/dados/foto";
reqHttp.getRequestDispatcher(novoCaminho).forward(reqHttp, resHttp);
cadeia.doFilter(reqHttp, resHttp);
return;
}
cadeia.doFilter(requisicao, resposta);
}
@Override
public void destroy() {
Filter.super.destroy();
}
}