Exemplo de Tutorial de Filtro Java Servlet

Java Servlet Filter é usado para interceptar a solicitação do cliente e realizar algum pré-processamento. Ele também pode interceptar a resposta e realizar pós-processamento antes de enviar ao cliente em uma aplicação web. Este é o quarto artigo da série Tutorial de Aplicações Web, você pode querer conferir os artigos anteriores também.

  1. Aplicação Web Java
  2. Tutorial Servlet Java
  3. Gerenciamento de Sessão Servlet

Filtro Servlet

Neste artigo, vamos aprender sobre o Filtro Servlet em Java. Vamos explorar vários usos do filtro servlet, como podemos criar um filtro e aprender seu uso com uma aplicação web simples.

  1. Por que temos o Filtro Servlet?

  2. Interface do Filtro Servlet

  3. Anotação WebFilter do Servlet

  4. Configuração do Filtro Servlet no web.xml

  5. Exemplo de Filtro Servlet para Logging e validação de sessão

  6. Porque temos um Filtro Servlet?

    No último artigo, aprendemos como podemos gerenciar sessões em aplicativos da web e, se quisermos garantir que um recurso seja acessível apenas quando a sessão do usuário for válida, podemos conseguir isso usando atributos de sessão do servlet. A abordagem é simples, mas se tivermos muitos servlets e jsps, será difícil de manter devido ao código redundante. Se quisermos alterar o nome do atributo no futuro, teremos que alterar todos os lugares onde temos autenticação de sessão. É por isso que temos um filtro servlet. Os filtros servlet são componentes java plugáveis que podemos usar para interceptar e processar solicitações antes de serem enviadas aos servlets e resposta após o código do servlet ser concluído e antes que o contêiner envie a resposta de volta ao cliente. Algumas tarefas comuns que podemos fazer com os filtros servlet são:

    • Registro de parâmetros de solicitação em arquivos de log.
    • Autenticação e autorização de solicitação de recursos.
    • Formatação do corpo ou cabeçalho da solicitação antes de enviá-lo ao servlet.
    • Compactação dos dados de resposta enviados ao cliente.
    • Alteração da resposta adicionando alguns cookies, informações de cabeçalho, etc.

    Como mencionei anteriormente, os filtros servlet são plugáveis e configurados no arquivo de descritor de implantação (web.xml). Servlets e filtros não têm conhecimento um do outro e podemos adicionar ou remover um filtro servlet apenas editando o web.xml. Podemos ter vários filtros para um único recurso e podemos criar uma cadeia de filtros para um único recurso no web.xml. Podemos criar um Filtro Servlet implementando a interface javax.servlet.Filter.

  7. Interface do Filtro Servlet

    A interface do Filtro Servlet é semelhante à interface do Servlet e precisamos implementá-la para criar nosso próprio filtro de servlet. A interface do Filtro Servlet contém métodos do ciclo de vida de um Filtro e é gerenciada pelo contêiner de servlet. Os métodos do ciclo de vida da interface do Filtro Servlet são:

    1. void init(FilterConfig paramFilterConfig) – Quando o contêiner inicializa o Filtro, este é o método que é invocado. Este método é chamado apenas uma vez no ciclo de vida do filtro e devemos inicializar quaisquer recursos neste método. FilterConfig é usado pelo contêiner para fornecer parâmetros de inicialização e objeto de contexto de servlet ao Filtro. Podemos lançar ServletException neste método.
    2. doFilter(ServletRequest paramServletRequest, ServletResponse paramServletResponse, FilterChain paramFilterChain) – Este é o método invocado todas as vezes pelo contêiner quando ele precisa aplicar filtro a um recurso. O Contêiner fornece referências de objetos de solicitação e resposta ao filtro como argumento. FilterChain é usado para invocar o próximo filtro na cadeia. Este é um ótimo exemplo do Padrão de Cadeia de Responsabilidade.
    3. void destroy() – Quando o contêiner descarta a instância do Filtro, ele invoca o método destroy(). Este é o método onde podemos fechar quaisquer recursos abertos pelo filtro. Este método é chamado apenas uma vez na vida do filtro.
  8. Anotação Servlet WebFilter

    javax.servlet.annotation.WebFilter foi introduzido no Servlet 3.0 e podemos usar essa anotação para declarar um filtro de servlet. Podemos usar esta anotação para definir parâmetros de inicialização, nome e descrição do filtro, servlets, padrões de URL e tipos de despachante para aplicar o filtro. Se você fizer alterações frequentes nas configurações do filtro, é melhor usar o arquivo web.xml, pois isso não exigirá que você recompile a classe do filtro. Leia: Tutorial de Anotações Java

  9. Configuração do Filtro Servlet no web.xml

    Podemos declarar um filtro Servlet no web.xml da seguinte maneira.

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

    Podemos mapear um filtro para classes Servlet ou padrões de URL da seguinte maneira.

    <filter-mapping>
      <filter-name>RequestLoggingFilter</filter-name> <!-- obrigatório -->
      <url-pattern>/*</url-pattern> <!-- tanto url-pattern quanto servlet-name são obrigatórios -->
      <servlet-name>LoginServlet</servlet-name>
      <dispatcher>REQUEST</dispatcher>
    </filter-mapping>
    

    Nota: Ao criar a cadeia de filtros para um servlet, o contêiner processa primeiro os padrões de URL e, em seguida, os nomes dos servlets. Portanto, se você precisa garantir que os filtros sejam executados em uma ordem específica, preste atenção extra ao definir o mapeamento do filtro. Os filtros Servlet são geralmente usados para solicitações de clientes, mas às vezes queremos aplicar filtros com RequestDispatcher também. Podemos usar o elemento dispatcher nesse caso, os valores possíveis são REQUEST, FORWARD, INCLUDE, ERROR e ASYNC. Se nenhum dispatcher for definido, ele será aplicado apenas a solicitações de clientes.

  10. Exemplo de Filtro Servlet para Logging e validação de sessão

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 { // obter parâmetros de solicitação para userID e senha 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"); // configurar a sessão para expirar em 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 acesso apenas se a sessão existir 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 a sessão se existir 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()+"}"); } } // passar a solicitação ao longo da cadeia de filtros chain.doFilter(request, response); } public void destroy() { // podemos fechar recursos aqui } } ``` ``` 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{ // passar a solicitação ao longo da cadeia de filtros chain.doFilter(request, response); } } public void destroy() { // fechar quaisquer recursos aqui } } ``` 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 ```

Isso é tudo para o Filtro Servlet em java. É uma das características importantes da aplicação web Java EE e devemos usá-la para tarefas comuns realizadas por vários servlets. Em postagens futuras, examinaremos ouvintes de servlet e cookies. Atualização: Após receber muitos pedidos pelo projeto para download, eu o anexei à postagem, faça o download no link abaixo.

Download do Projeto Exemplo de Filtro Servlet

Confira o próximo artigo da série sobre Servlet Listener. Atualização O Struts 2 usa Servlet Filter para interceptar as solicitações do cliente e encaminhá-las para as classes de ação apropriadas, chamadas de Struts 2 Interceptors. Confira Tutorial para Iniciantes no Struts 2.

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