En el ecosistema de Spring Boot, el manejo de peticionees HTTP a menudo requiere lógica transversal como la validación de tokens, gestión de CORS o auditoría. Para estas tareas, disponemos de dos mecanismos principales: los Interceptores y los Filtros.
1. Interceptores de Spring MVC
Los interceptores forman parte del framwork Spring MVC y operan entre el DispatcherServlet y los controladores. Para implementar uno de manera efectiva, existen diversas aproximaciones:
- WebMvcConfigurer: Es la opción recomendada actualmente, ya que permite definir la configuración de forma modular sin invalidar la autoconfiguración de Spring Boot.
- WebMvcConfigurationSupport: Proporciona un control total, pero desactiva las configuraciones automáticas de MVC de Spring Boot, por lo que debe usarse con precaución.
- WebMvcConfigurerAdapter: Opción obsoleta desde Spring 5.0.
A continuación, se muestra cómo registrar un interceptor de seguridad personalizado:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class AppWebMvcConfig implements WebMvcConfigurer {
@Autowired
private SecurityHandlerInterceptor securityHandlerInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// Registro del interceptor definiendo rutas protegidas y excluidas
registry.addInterceptor(securityHandlerInterceptor)
.addPathPatterns("/api/v1/**")
.excludePathPatterns("/api/v1/auth/login")
.excludePathPatterns("/api/v1/public/**")
.excludePathPatterns("/swagger-ui/**");
}
}
2. Filtros de Servlet
Los filtros operan a un nivel inferior, directamente en el contenedor de servlets (como Tomcat). Son ideales para tareas que no requieren el contexto completo de Spring MVC, como la modificación de cabeceras HTTP o la compresión de respuestas.
Ejemplo de un filtro para la gestión de cabeceras de control de acceso (CORS):
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class CustomHeaderFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// Lógica de inicialización si es necesaria
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse httpResponse = (HttpServletResponse) response;
// Configuración de cabeceras personalizadas
httpResponse.setHeader("Access-Control-Allow-Origin", "*");
httpResponse.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
httpResponse.setHeader("X-App-Version", "1.0.0");
// Continuar con la cadena de ejecución
chain.doFilter(request, response);
}
@Override
public void destroy() {
// Limpieza de recursos
}
}
Registro de Filtros mediante Beans
En Spring Boot, la forma más limpia de registrar filtros y controlar su orden o patronse de URL es mediante un FilterRegistrationBean.
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FilterRegistrationConfig {
@Bean
public FilterRegistrationBean<CustomHeaderFilter> loggingFilterRegistration() {
FilterRegistrationBean<CustomHeaderFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new CustomHeaderFilter());
// Aplicar el filtro solo a rutas específicas
registrationBean.addUrlPatterns("/api/*");
// Establecer prioridad en la cadena de filtros
registrationBean.setOrder(1);
return registrationBean;
}
}
Al elegir entre ambos, recuerde que los filtros son más adecuados para tareas globales de infraestructura, mientras que los interceptores son preferibles cuando se necesita interactuar con la lógica de negocio o los objetos de Spring MVC (como los Handlers).