Servlets y JSP: tutorial Jakarta EE 10 y Java 21

Los filtros interceptan peticiones antes y después de que lleguen al Servlet o a la JSP. Los listeners reaccionan a eventos del ciclo de vida de la aplicación, la sesión y la petición.

Filtros: casos de uso comunes

  • Autenticación y autorización (como vimos antes).
  • Logging de peticiones.
  • Compresión GZIP de la respuesta.
  • Establecer codificación de caracteres.
  • Cabeceras de seguridad (CORS, CSP, X-Frame-Options).
@WebFilter("/*")
public class LoggingFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        long inicio = System.currentTimeMillis();

        chain.doFilter(req, resp); // ejecutar el Servlet/JSP

        long duracion = System.currentTimeMillis() - inicio;
        System.out.printf("[%s] %s %s → %dms%n",
            LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME),
            request.getMethod(),
            request.getRequestURI(),
            duracion
        );
    }
}

Filtro de cabeceras de seguridad

@WebFilter("/*")
public class SecurityHeadersFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
            throws IOException, ServletException {

        HttpServletResponse response = (HttpServletResponse) resp;
        response.setHeader("X-Content-Type-Options", "nosniff");
        response.setHeader("X-Frame-Options", "SAMEORIGIN");
        response.setHeader("X-XSS-Protection", "1; mode=block");
        response.setHeader("Referrer-Policy", "strict-origin-when-cross-origin");
        // HSTS solo si usas HTTPS
        // response.setHeader("Strict-Transport-Security", "max-age=31536000; includeSubDomains");

        chain.doFilter(req, resp);
    }
}

Listeners

// Escuchar eventos del contexto (aplicación)
@WebListener
public class AppContextListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        // Se ejecuta al arrancar la aplicación
        ServletContext ctx = sce.getServletContext();
        ctx.setAttribute("version", "1.0.0");
        ctx.setAttribute("arranque", LocalDateTime.now());
        System.out.println("Aplicación iniciada");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("Aplicación detenida");
        // Cerrar conexiones a BD, apagar hilos, etc.
    }
}

// Escuchar eventos de sesión
@WebListener
public class SessionListener implements HttpSessionListener {

    private final AtomicInteger activas = new AtomicInteger();

    @Override
    public void sessionCreated(HttpSessionEvent se) {
        int n = activas.incrementAndGet();
        System.out.println("Nueva sesión. Activas: " + n);
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        activas.decrementAndGet();
    }
}

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP
ARTÍCULO ANTERIOR