Java Servlet Filter Voorbeeld Zelfstudie

Java Servlet Filter wordt gebruikt om het clientverzoek te onderscheppen en enige voorverwerking uit te voeren. Het kan ook de respons onderscheppen en postverwerking uitvoeren voordat deze naar de client wordt verzonden in een webtoepassing. Dit is het vierde artikel in de reeks Webapplicatietutorial; je wilt misschien ook eerdere artikelen bekijken.

  1. Java-webtoepassing
  2. Java Servlet-zelfstudie
  3. Servlet-sessiebeheer

Servlet-filter

In dit artikel zullen we leren over het Servlet-filter in Java. We zullen verschillende toepassingen van het servlet-filter bekijken, hoe we een filter kunnen maken en de toepassing ervan leren met een eenvoudige webtoepassing.

  1. Waarom hebben we een Servlet-filter?

  2. Servlet-filterinterface

  3. Servlet WebFilter-annotatie

  4. Servlet Filter configuratie in web.xml

  5. Voorbeeld van Servlet Filter voor logging en sessievalidatie

  6. Waarom hebben we een Servlet-filter?

    In het laatste artikel hebben we geleerd hoe we sessies kunnen beheren in een webapplicatie. Als we ervoor willen zorgen dat een bron alleen toegankelijk is wanneer de gebruikerssessie geldig is, kunnen we dit bereiken met behulp van servlet-sessieattributen. De aanpak is eenvoudig, maar als we veel servlets en JSP’s hebben, wordt het moeilijk te onderhouden vanwege redundante code. Als we in de toekomst de attribuutnaam willen wijzigen, moeten we alle plaatsen waar we sessie-authenticatie hebben, aanpassen. Daarom hebben we een servlet-filter. Servlet-filters zijn plug-in Java-componenten die we kunnen gebruiken om verzoeken te onderscheppen en te verwerken voordat ze naar servlets worden gestuurd en de respons nadat de servletcode is voltooid en voordat de container de respons naar de client terugstuurt. Enkele veelvoorkomende taken die we met servlet-filters kunnen uitvoeren, zijn:

    • Loggen van verzoekparameters naar logbestanden.
    • Authenticatie en autorisatie van verzoeken voor bronnen.
    • Opmaak van verzoekbody of -header voordat deze naar de servlet wordt verzonden.
    • Comprimeren van de responsgegevens die naar de client worden verzonden.
    • De respons wijzigen door het toevoegen van enkele cookies, kopgegevens, enz.

    Zoals ik eerder heb vermeld, zijn servlet-filters plug-in en geconfigureerd in het inzetbeschrijvingsbestand (web.xml). Servlets en filters zijn zich niet bewust van elkaar, en we kunnen een servlet-filter toevoegen of verwijderen door eenvoudigweg web.xml te bewerken. We kunnen meerdere filters hebben voor een enkele bron en een keten van filters maken voor een enkele bron in web.xml. We kunnen een Servlet-filter maken door de interface javax.servlet.Filter te implementeren.

  7. Servlet Filter interface

    Het Servlet Filter-interface is vergelijkbaar met het Servlet-interface en we moeten het implementeren om onze eigen servletfilter te maken. Het Servlet Filter-interface bevat levenscyclusmethoden van een filter en het wordt beheerd door de servletcontainer. De levenscyclusmethoden van het Servlet Filter-interface zijn:

    1. void init(FilterConfig paramFilterConfig) – Wanneer de container de Filter initialiseert, wordt deze methode aangeroepen. Deze methode wordt slechts één keer aangeroepen tijdens de levenscyclus van het filter en we moeten eventuele bronnen initialiseren in deze methode. FilterConfig wordt door de container gebruikt om init-parameters en het servletcontextobject aan het filter te verstrekken. We kunnen ServletException in deze methode gooien.
    2. doFilter(ServletRequest paramServletRequest, ServletResponse paramServletResponse, FilterChain paramFilterChain) – Dit is de methode die door de container wordt aangeroepen telkens wanneer het filter moet worden toegepast op een bron. De container levert referenties naar het verzoek- en responsobject aan het filter als argument. FilterChain wordt gebruikt om het volgende filter in de keten aan te roepen. Dit is een goed voorbeeld van Chain of Responsibility Pattern.
    3. void destroy() – Wanneer de container de Filter-instantie verwijdert, roept het de destroy() methode aan. Dit is de methode waar we eventuele bronnen kunnen sluiten die door het filter zijn geopend. Deze methode wordt slechts één keer aangeroepen tijdens de levensduur van het filter.
  8. Servlet WebFilter-annotatie

    javax.servlet.annotation.WebFilter werd geïntroduceerd in Servlet 3.0 en we kunnen deze annotatie gebruiken om een servletfilter te declareren. We kunnen deze annotatie gebruiken om initialisatieparameters, filternaam en -beschrijving, servlets, URL-patronen en dispatcher-typen te definiëren om de filter toe te passen. Als je vaak wijzigingen aanbrengt in de filterconfiguraties, is het beter om web.xml te gebruiken omdat dit niet vereist dat je de filterklasse opnieuw compileert. Lees: Java Annotations Tutorial

  9. Servletfilterconfiguratie in web.xml

    We kunnen een servletfilter declareren in web.xml zoals hieronder.

    <filter>
      <filter-name>RequestLoggingFilter</filter-name> <!-- verplicht -->
      <filter-class>com.journaldev.servlet.filters.RequestLoggingFilter</filter-class> <!-- verplicht -->
      <init-param> <!-- optioneel -->
      <param-name>test</param-name>
      <param-value>testWaarde</param-value>
      </init-param>
    </filter>
    

    We kunnen een filter toewijzen aan servletklassen of url-patronen zoals hieronder.

    <filter-mapping>
      <filter-name>RequestLoggingFilter</filter-name> <!-- verplicht -->
      <url-pattern>/*</url-pattern> <!-- ofwel url-pattern of servlet-name is verplicht -->
      <servlet-name>LoginServlet</servlet-name>
      <dispatcher>REQUEST</dispatcher>
    </filter-mapping>
    

    Opmerking: bij het maken van de filterketen voor een servlet verwerkt de container eerst de url-patronen en vervolgens de servlet-namen, dus als u ervoor moet zorgen dat filters in een bepaalde volgorde worden uitgevoerd, besteed dan extra aandacht bij het definiëren van de filtertoewijzing. Servletfilters worden over het algemeen gebruikt voor clientverzoeken, maar soms willen we filters ook toepassen met RequestDispatcher, in dat geval kunnen we het dispatcher-element gebruiken, de mogelijke waarden zijn REQUEST, FORWARD, INCLUDE, ERROR en ASYNC. Als er geen dispatcher is gedefinieerd, wordt het alleen toegepast op clientverzoeken.

  10. Voorbeeld van een Servlet Filter voor logging en sessievalidatie

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 { // haal verzoekparameters op voor gebruikers-ID en wachtwoord 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"); // instellen van sessie om na 30 minuten te verlopen 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 <% // toegang alleen toestaan als sessie bestaat 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; } } } // ongeldig maken van de sessie indien deze bestaat 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()+"}"); } } // stuur het verzoek door langs de filterketen chain.doFilter(request, response); } public void destroy() { // hier kunnen we bronnen sluiten } } ``` ``` 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{ // stuur het verzoek door langs de filterketen chain.doFilter(request, response); } } public void destroy() { // sluit hier eventuele bronnen af } } ``` 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 ```

Dat is alles voor Servlet Filter in Java. Het is een van de belangrijke functies van Java EE-webapplicaties en we zouden het moeten gebruiken voor gemeenschappelijke taken die worden uitgevoerd door verschillende servlets. In toekomstige berichten zullen we kijken naar servletlisteners en cookies. Update: Na veel verzoeken om het downloadbare project, heb ik het bij het bericht gevoegd, download het van de onderstaande link.

Download Servlet Filter Voorbeeldproject

Bekijk het volgende artikel in de reeks over Servlet Listener. Update Struts 2 gebruikt een Servlet Filter om de clientverzoeken te onderscheppen en door te sturen naar de juiste actieklassen, deze worden Struts 2 Interceptors genoemd. Bekijk de Struts 2 Beginners Tutorial.

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