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 enviá-la ao cliente em uma aplicação web. Este é o quarto artigo na série Tutorial de Aplicações Web, talvez você queira conferir os artigos anteriores também.

  1. Java Web Application
  2. Java Servlet Tutorial
  3. Servlet Session Management

Servlet Filter

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

  1. Por que temos o Servlet Filter?

  2. Interface do Filtro do Servlet

  3. Anotação Servlet WebFilter

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

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

  6. Por que temos o Servlet Filter?

    No último artigo, aprendemos como podemos gerenciar a sessão em uma aplicação 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 os atributos de sessão do servlet. A abordagem é simples, mas se tivermos muitos servlets e jsps, então se tornará difícil de manter devido ao código redundante. Se quisermos mudar 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 de servlet. Os filtros de servlet são componentes java plugáveis que podemos usar para interceptar e processar solicitações antes de serem enviadas para os servlets e resposta depois que o código do servlet é concluído e antes que o contêiner envie a resposta de volta para o cliente. Algumas tarefas comuns que podemos fazer com filtros de servlet são:

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

    Como mencionei anteriormente, os filtros de servlet são plugáveis e configurados no arquivo de descritor de implantação (web.xml). Os servlets e filtros são desconhecidos entre si e podemos adicionar ou remover um filtro de 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 de Servlet implementando a interface javax.servlet.Filter.

  7. Interface do Filtro Servlet

    A interface do Filtro Servlet é semelhante à interface Servlet e precisamos implementá-la para criar nosso próprio filtro de servlet. A interface do Filtro Servlet contém métodos de 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 para o Filtro. Podemos lançar ServletException neste método.
    2. doFilter(ServletRequest paramServletRequest, ServletResponse paramServletResponse, FilterChain paramFilterChain) – Este é o método invocado sempre pelo contêiner quando ele precisa aplicar o filtro a um recurso. O contêiner fornece referências de objeto de solicitação e resposta para o filtro como argumento. FilterChain é usado para invocar o próximo filtro na cadeia. Este é um ótimo exemplo de Padrão Chain of Responsibility.
    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 útil do filtro.
  8. Anotação Servlet WebFilter

    javax.servlet.annotation.WebFilter foi introduzida no Servlet 3.0 e podemos usar esta 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 web.xml, porque 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 como abaixo.

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

    Podemos mapear um filtro para classes servlet ou padrões de URL como abaixo.

    <filter-mapping>
      <filter-name>RequestLoggingFilter</filter-name> <!-- obrigatório -->
      <url-pattern>/*</url-pattern> <!-- ou url-pattern ou servlet-name é obrigatório -->
      <servlet-name>LoginServlet</servlet-name>
      <dispatcher>REQUEST</dispatcher>
    </filter-mapping>
    

    Nota: Ao criar a cadeia de filtros para um servlet, o contêiner primeiro processa os padrões de URL e depois os nomes dos servlets, então, 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 neste caso, os valores possíveis são REQUEST, FORWARD, INCLUDE, ERROR e ASYNC. Se nenhum dispatcher for definido, ele é 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"); // definir 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á-lo para tarefas comuns realizadas por vários servlets. Em postagens futuras, vamos explorar ouvintes de servlets e cookies. Atualização: Após receber muitos pedidos para o projeto para download, eu o anexei à postagem, faça o download do link abaixo.

Baixar Projeto de Exemplo de Filtro Servlet

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

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