Ejemplo de Tutorial de Filtro Servlet Java

Java Servlet Filter se utiliza para interceptar la solicitud del cliente y realizar algún preprocesamiento. También puede interceptar la respuesta y realizar un postprocesamiento antes de enviarla al cliente en una aplicación web. Este es el cuarto artículo de la serie de Tutoriales de Aplicaciones Web. Es posible que desees revisar los artículos anteriores también.

  1. Aplicación Web Java
  2. Tutorial de Servlet Java
  3. Administración de Sesiones en Servlet

Filtro Servlet

En este artículo, aprenderemos sobre el Filtro Servlet en Java. Exploraremos varios usos del filtro servlet, cómo podemos crear un filtro y aprenderemos su uso con una aplicación web simple.

  1. ¿Por qué tenemos un Filtro Servlet?

  2. Interfaz de Filtro Servlet

  3. Anotación de Filtro Web Servlet

  4. Configuración del filtro Servlet en web.xml

  5. Ejemplo de filtro Servlet para registro y validación de sesión

  6. ¿Por qué tenemos un Filtro Servlet?

    En el último artículo, aprendimos cómo podemos gestionar la sesión en una aplicación web y si queremos asegurarnos de que un recurso solo sea accesible cuando la sesión del usuario sea válida, podemos lograrlo utilizando atributos de sesión de servlet. El enfoque es simple, pero si tenemos muchos servlets y JSP, entonces será difícil de mantener debido al código redundante. Si queremos cambiar el nombre del atributo en el futuro, tendremos que cambiar todos los lugares donde tenemos autenticación de sesión. Es por eso que tenemos un filtro de servlet. Los filtros de servlet son componentes Java enchufables que podemos usar para interceptar y procesar solicitudes antes de que se envíen a los servlets y la respuesta después de que el código del servlet haya terminado y antes de que el contenedor envíe la respuesta de vuelta al cliente. Algunas tareas comunes que podemos hacer con los filtros de servlet son:

    • Registrar parámetros de solicitud en archivos de registro.
    • Autenticación y autorización de solicitudes de recursos.
    • Formato del cuerpo o encabezado de la solicitud antes de enviarlo al servlet.
    • Comprimir los datos de respuesta enviados al cliente.
    • Modificar la respuesta agregando algunas cookies, información de encabezado, etc.

    Como mencioné anteriormente, los filtros de servlet son enchufables y se configuran en el archivo descriptor de implementación (web.xml). Los servlets y los filtros no se conocen entre sí y podemos agregar o eliminar un filtro de servlet simplemente editando web.xml. Podemos tener varios filtros para un solo recurso y podemos crear una cadena de filtros para un solo recurso en web.xml. Podemos crear un Filtro Servlet implementando la interfaz javax.servlet.Filter.

  7. Interfaz del Filtro Servlet

    La interfaz del Filtro Servlet es similar a la interfaz Servlet y necesitamos implementarla para crear nuestro propio filtro servlet. La interfaz del Filtro Servlet contiene los métodos del ciclo de vida de un filtro y es gestionada por el contenedor servlet. Los métodos del ciclo de vida de la interfaz del Filtro Servlet son:

    1. void init(FilterConfig paramFilterConfig) – Cuando el contenedor inicializa el filtro, este es el método que se invoca. Este método se llama solo una vez en el ciclo de vida del filtro y deberíamos inicializar cualquier recurso en este método. FilterConfig es utilizado por el contenedor para proporcionar parámetros de inicialización y el objeto de contexto del servlet al filtro. Podemos lanzar ServletException en este método.
    2. doFilter(ServletRequest paramServletRequest, ServletResponse paramServletResponse, FilterChain paramFilterChain) – Este es el método invocado cada vez por el contenedor cuando tiene que aplicar el filtro a un recurso. El contenedor proporciona referencias de objetos de solicitud y respuesta al filtro como argumento. FilterChain es utilizado para invocar el siguiente filtro en la cadena. Este es un excelente ejemplo del Patrón de Cadena de Responsabilidad.
    3. void destroy() – Cuando el contenedor descarga la instancia del filtro, invoca el método destroy(). Este es el método donde podemos cerrar cualquier recurso abierto por el filtro. Este método se llama solo una vez en la vida del filtro.
  8. Anotación Servlet WebFilter

    javax.servlet.annotation.WebFilter fue introducida en Servlet 3.0 y podemos usar esta anotación para declarar un filtro de servlet. Podemos utilizar esta anotación para definir parámetros de inicialización, nombre y descripción del filtro, servlets, patrones de URL y tipos de despachador para aplicar el filtro. Si realiza cambios frecuentes en las configuraciones del filtro, es mejor utilizar web.xml porque no requerirá recompilar la clase del filtro. Leer: Tutorial de Anotaciones en Java

  9. Configuración del Filtro Servlet en web.xml

    Podemos declarar un filtro servlet en web.xml de la siguiente manera.

    <filter>
      <filter-name>RequestLoggingFilter</filter-name> <!-- obligatorio -->
      <filter-class>com.journaldev.servlet.filters.RequestLoggingFilter</filter-class> <!-- obligatorio -->
      <init-param> <!-- opcional -->
      <param-name>test</param-name>
      <param-value>testValue</param-value>
      </init-param>
    </filter>
    

    Podemos mapear un filtro a clases de servlet o url-patrones de la siguiente manera.

    <filter-mapping>
      <filter-name>RequestLoggingFilter</filter-name> <!-- obligatorio -->
      <url-pattern>/*</url-pattern> <!-- ya sea url-pattern o servlet-name es obligatorio -->
      <servlet-name>LoginServlet</servlet-name>
      <dispatcher>REQUEST</dispatcher>
    </filter-mapping>
    

    Nota: Al crear la cadena de filtros para un servlet, el contenedor procesa primero los url-patrones y luego los nombres de servlet, por lo que si debe asegurarse de que los filtros se ejecuten en un orden específico, preste especial atención al definir el mapeo del filtro. Los filtros servlet se utilizan generalmente para las solicitudes de cliente, pero a veces queremos aplicar filtros también con RequestDispatcher, en este caso, podemos usar el elemento dispatcher, los valores posibles son REQUEST, FORWARD, INCLUDE, ERROR y ASYNC. Si no se define ningún dispatcher, se aplica solo a las solicitudes de cliente.

  10. Ejemplo de filtro Servlet para registro y validación de sesión

In our **servlet filter example**, we will create filters to log request cookies and parameters and validate session to all the resources except static HTMLs and LoginServlet because it will not have a session. We will create a dynamic web project **ServletFilterExample** whose project structure will look like the below image. [![Servlet Filter Example, Java Filter](https://journaldev.nyc3.cdn.digitaloceanspaces.com/2013/08/Servlet-Filter-Example-Project.png)](https://journaldev.nyc3.cdn.digitaloceanspaces.com/2013/08/Servlet-Filter-Example-Project.png) login.html is the entry point of our application where the user will provide the login id and password for authentication. login.html code:

```



























Login Page


Username:
Password:
``` LoginServlet is used to authenticate the request from the client for login. ``` package com.journaldev.servlet.session; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; /** * Servlet implementation class LoginServlet */ @WebServlet("/LoginServlet") public class LoginServlet extends HttpServlet { private static final long serialVersionUID = 1L; private final String userID = "admin"; private final String password = "password"; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // obtener parámetros de solicitud para userID y contraseña String user = request.getParameter("user"); String pwd = request.getParameter("pwd"); if(userID.equals(user) && password.equals(pwd)){ HttpSession session = request.getSession(); session.setAttribute("user", "Pankaj"); // establecer la sesión para que expire en 30 minutos session.setMaxInactiveInterval(30*60); Cookie userName = new Cookie("user", user); userName.setMaxAge(30*60); response.addCookie(userName); response.sendRedirect("LoginSuccess.jsp"); }else{ RequestDispatcher rd = getServletContext().getRequestDispatcher("/login.html"); PrintWriter out= response.getWriter(); out.println("Either user name or password is wrong."); rd.include(request, response); } } } ``` When the client is authenticated, it's forwarded to LoginSuccess.jsp LoginSuccess.jsp code: ``` <%@ page language="java" contentType="text/html; charset=US-ASCII" pageEncoding="US-ASCII"%> Login Success Page <% // permitir acceso solo si la sesión existe String user = (String) session.getAttribute("user"); String userName = null; String sessionID = null; Cookie[] cookies = request.getCookies(); if(cookies !=null){ for(Cookie cookie : cookies){ if(cookie.getName().equals("user")) userName = cookie.getValue(); if(cookie.getName().equals("JSESSIONID")) sessionID = cookie.getValue(); } } %>

Hi <%=userName %>, Login successful. Your Session ID=<%=sessionID %>


User=<%=user %>
Checkout Page
``` Notice that there is no session validation logic in the above JSP. It contains a link to another JSP page, CheckoutPage.jsp. CheckoutPage.jsp code: ``` <%@ page language="java" contentType="text/html; charset=US-ASCII" pageEncoding="US-ASCII"%> Login Success Page <% String userName = null; String sessionID = null; Cookie[] cookies = request.getCookies(); if(cookies !=null){ for(Cookie cookie : cookies){ if(cookie.getName().equals("user")) userName = cookie.getValue(); } } %>

Hi <%=userName %>, do the checkout.


``` LogoutServlet is invoked when a client clicks on the Logout button in any of the JSP pages. ``` package com.journaldev.servlet.session; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; /** * Servlet implementation class LogoutServlet */ @WebServlet("/LogoutServlet") public class LogoutServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); Cookie[] cookies = request.getCookies(); if(cookies != null){ for(Cookie cookie : cookies){ if(cookie.getName().equals("JSESSIONID")){ System.out.println("JSESSIONID="+cookie.getValue()); break; } } } // invalidar la sesión si existe HttpSession session = request.getSession(false); System.out.println("User="+session.getAttribute("user")); if(session != null){ session.invalidate(); } response.sendRedirect("login.html"); } } ``` Now we will create logging and authentication servlet filter classes. ``` package com.journaldev.servlet.filters; import java.io.IOException; import java.util.Enumeration; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; /** * Servlet Filter implementation class RequestLoggingFilter */ @WebFilter("/RequestLoggingFilter") public class RequestLoggingFilter implements Filter { private ServletContext context; public void init(FilterConfig fConfig) throws ServletException { this.context = fConfig.getServletContext(); this.context.log("RequestLoggingFilter initialized"); } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; Enumeration params = req.getParameterNames(); while(params.hasMoreElements()){ String name = params.nextElement(); String value = request.getParameter(name); this.context.log(req.getRemoteAddr() + "::Request Params::{"+name+"="+value+"}"); } Cookie[] cookies = req.getCookies(); if(cookies != null){ for(Cookie cookie : cookies){ this.context.log(req.getRemoteAddr() + "::Cookie::{"+cookie.getName()+","+cookie.getValue()+"}"); } } // pasar la solicitud a lo largo de la cadena de filtros chain.doFilter(request, response); } public void destroy() { // aquí podemos cerrar recursos } } ``` ``` package com.journaldev.servlet.filters; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; @WebFilter("/AuthenticationFilter") public class AuthenticationFilter implements Filter { private ServletContext context; public void init(FilterConfig fConfig) throws ServletException { this.context = fConfig.getServletContext(); this.context.log("AuthenticationFilter initialized"); } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; String uri = req.getRequestURI(); this.context.log("Requested Resource::"+uri); HttpSession session = req.getSession(false); if(session == null && !(uri.endsWith("html") || uri.endsWith("LoginServlet"))){ this.context.log("Unauthorized access request"); res.sendRedirect("login.html"); }else{ // pasar la solicitud a lo largo de la cadena de filtros chain.doFilter(request, response); } } public void destroy() { // cerrar cualquier recurso aquí } } ``` Notice that we are not authenticating any HTML page or LoginServlet. Now we will configure these filters mapping in the web.xml file. ``` ServletFilterExample login.html RequestLoggingFilter com.journaldev.servlet.filters.RequestLoggingFilter AuthenticationFilter com.journaldev.servlet.filters.AuthenticationFilter RequestLoggingFilter /* REQUEST AuthenticationFilter /* ``` Now when we will run our application, we will get response pages like below images. [![Servlet Filter Example](https://journaldev.nyc3.cdn.digitaloceanspaces.com/2013/08/Servlet-Filter-Login-450x141.png)](https://journaldev.nyc3.cdn.digitaloceanspaces.com/2013/08/Servlet-Filter-Login.png) [![Servlet Filter, Java Filter](https://journaldev.nyc3.cdn.digitaloceanspaces.com/2013/08/Servlet-Filter-Login-Success-450x229.png)](https://journaldev.nyc3.cdn.digitaloceanspaces.com/2013/08/Servlet-Filter-Login-Success.png) [![Servlet Filter Tutorial, Java Servlet Filter](https://journaldev.nyc3.cdn.digitaloceanspaces.com/2013/08/Servlet-Filter-Checkout-450x181.png)](https://journaldev.nyc3.cdn.digitaloceanspaces.com/2013/08/Servlet-Filter-Checkout.png) If you are not logged in and try to access any JSP page, you will be forwarded to the login page. In the server log file, you can see the logs written by servlet filters as well as servlets. ``` Aug 13, 2013 1:06:07 AM org.apache.catalina.core.ApplicationContext log INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,B7275762B8D23121152B1270D6EB240A} Aug 13, 2013 1:06:07 AM org.apache.catalina.core.ApplicationContext log INFO: Requested Resource::/ServletFilterExample/ Aug 13, 2013 1:06:07 AM org.apache.catalina.core.ApplicationContext log INFO: Unauthorized access request Aug 13, 2013 1:06:07 AM org.apache.catalina.core.ApplicationContext log INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,B7275762B8D23121152B1270D6EB240A} Aug 13, 2013 1:06:07 AM org.apache.catalina.core.ApplicationContext log INFO: Requested Resource::/ServletFilterExample/login.html Aug 13, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log INFO: 0:0:0:0:0:0:0:1%0::Request Params::{pwd=password} Aug 13, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log INFO: 0:0:0:0:0:0:0:1%0::Request Params::{user=admin} Aug 13, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,B7275762B8D23121152B1270D6EB240A} Aug 13, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log INFO: Requested Resource::/ServletFilterExample/LoginServlet Aug 13, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56} Aug 13, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin} Aug 13, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log INFO: Requested Resource::/ServletFilterExample/LoginSuccess.jsp Aug 13, 2013 1:06:52 AM org.apache.catalina.core.ApplicationContext log INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56} Aug 13, 2013 1:06:52 AM org.apache.catalina.core.ApplicationContext log INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin} Aug 13, 2013 1:06:52 AM org.apache.catalina.core.ApplicationContext log INFO: Requested Resource::/ServletFilterExample/CheckoutPage.jsp Aug 13, 2013 1:07:00 AM org.apache.catalina.core.ApplicationContext log INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56} Aug 13, 2013 1:07:00 AM org.apache.catalina.core.ApplicationContext log INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin} Aug 13, 2013 1:07:00 AM org.apache.catalina.core.ApplicationContext log INFO: Requested Resource::/ServletFilterExample/LogoutServlet JSESSIONID=8BDF777933194EDCAC1D8F1B73633C56 User=Pankaj Aug 13, 2013 1:07:00 AM org.apache.catalina.core.ApplicationContext log INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56} Aug 13, 2013 1:07:00 AM org.apache.catalina.core.ApplicationContext log INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin} Aug 13, 2013 1:07:00 AM org.apache.catalina.core.ApplicationContext log INFO: Requested Resource::/ServletFilterExample/login.html Aug 13, 2013 1:07:06 AM org.apache.catalina.core.ApplicationContext log INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56} Aug 13, 2013 1:07:07 AM org.apache.catalina.core.ApplicationContext log INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin} Aug 13, 2013 1:07:07 AM org.apache.catalina.core.ApplicationContext log INFO: Requested Resource::/ServletFilterExample/LoginSuccess.jsp Aug 13, 2013 1:07:07 AM org.apache.catalina.core.ApplicationContext log INFO: Unauthorized access request Aug 13, 2013 1:07:07 AM org.apache.catalina.core.ApplicationContext log INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56} Aug 13, 2013 1:07:07 AM org.apache.catalina.core.ApplicationContext log INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin} Aug 13, 2013 1:07:07 AM org.apache.catalina.core.ApplicationContext log INFO: Requested Resource::/ServletFilterExample/login.html ```

Eso es todo para el Filtro Servlet en Java. Es una de las características importantes de la aplicación web Java EE y deberíamos usarlo para tareas comunes realizadas por varios servlets. En futuras publicaciones, examinaremos los listeners de servlets y las cookies. Actualización: Después de recibir muchas solicitudes para el proyecto descargable, lo he adjuntado a la publicación, descárguelo desde el siguiente enlace.

Descargar Proyecto de Ejemplo de Filtro Servlet

Echa un vistazo al próximo artículo de la serie sobre Servlet Listener. Actualización Struts 2 utiliza Servlet Filter para interceptar las solicitudes del cliente y enviarlas a las clases de acción correspondientes; a estas se les llama Interceptors de Struts 2. Consulta Tutorial para Principiantes de Struts 2.

Source:
https://www.digitalocean.com/community/tutorials/java-servlet-filter-example-tutorial