Java Servlet 过滤器示例教程

Java Servlet 过滤器用于拦截客户端请求并进行一些预处理。它还可以拦截响应并在在 Web 应用程序中发送给客户端之前进行后处理。

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

服务过滤器

在本文中,我们将关注Java中的Servlet过滤器,我们将研究Servlet过滤器的各种用途,我们如何创建过滤器,并通过简单的Web应用程序学习其使用。

  1. Why do we have Servlet Filter?

  2. Servlet Filter interface

  3. Servlet WebFilter annotation

  4. Servlet Filter configuration in web.xml

  5. Servlet Filter Example for Logging and session validation

  6. Why do we have Servlet Filter?

    In the last article, we learned how we can manage session in web application and if we want to make sure that a resource is accessible only when the user session is valid, we can achieve this using servlet session attributes. The approach is simple but if we have a lot of servlets and jsps, then it will become hard to maintain because of redundant code. If we want to change the attribute name in the future, we will have to change all the places where we have session authentication. That's why we have a servlet filter. Servlet Filters are pluggable java components that we can use to intercept and process requests before they are sent to servlets and response after servlet code is finished and before container sends the response back to the client. Some common tasks that we can do with servlet filters are:- Logging request parameters to log files.

    • Authentication and autherization of request for resources.
    • Formatting of request body or header before sending it to servlet.
    • Compressing the response data sent to the client.
    • Alter response by adding some cookies, header information etc. As I mentioned earlier, servlet filters are pluggable and configured in deployment descriptor (web.xml) file. Servlets and filters both are unaware of each other and we can add or remove a servlet filter just by editing web.xml. We can have multiple filters for a single resource and we can create a chain of filters for a single resource in web.xml. We can create a Servlet Filter by implementing javax.servlet.Filter interface.
  7. Servlet Filter interface

    Servlet Filter interface is similar to Servlet interface and we need to implement it to create our own servlet filter. Servlet Filter interface contains lifecycle methods of a Filter and it's managed by servlet container. Servlet Filter interface lifecycle methods are:1. void init(FilterConfig paramFilterConfig) - When container initializes the Filter, this is the method that gets invoked. This method is called only once in the lifecycle of filter and we should initialize any resources in this method. FilterConfig is used by container to provide init parameters and servlet context object to the Filter. We can throw ServletException in this method. 2. doFilter(ServletRequest paramServletRequest, ServletResponse paramServletResponse, FilterChain paramFilterChain) - This is the method invoked every time by container when it has to apply filter to a resource. Container provides request and response object references to filter as argument. FilterChain is used to invoke the next filter in the chain. This is a great example of Chain of Responsibility Pattern. 3. void destroy() - When container offloads the Filter instance, it invokes the destroy() method. This is the method where we can close any resources opened by filter. This method is called only once in the lifetime of filter.

  8. Servlet WebFilter annotation

    javax.servlet.annotation.WebFilter was introduced in Servlet 3.0 and we can use this annotation to declare a servlet filter. We can use this annotation to define init parameters, filter name and description, servlets, url patterns and dispatcher types to apply the filter. If you make frequent changes to the filter configurations, its better to use web.xml because that will not require you to recompile the filter class. Read: Java Annotations Tutorial

  9. Servlet Filter configuration in web.xml

    We can declare a servlet filter in web.xml like below.<filter> <filter-name>RequestLoggingFilter</filter-name> <!-- mandatory --> <filter-class>com.journaldev.servlet.filters.RequestLoggingFilter</filter-class> <!-- mandatory --> <init-param> <!-- optional --> <param-name>test</param-name> <param-value>testValue</param-value> </init-param> </filter>We can map a Filter to servlet classes or url-patterns like below.``` RequestLoggingFilter /* LoginServlet REQUEST

  10. Servlet Filter Example for Logging and session validation

    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 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 {

        // get request parameters for userID and password
        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");
        	//setting session to expiry in 30 mins
        	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("<font color=red>Either user name or password is wrong.</font>");
        	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<% //allow access only if session exists 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; } } } //invalidate the session if exists 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()+"}");
        	}
        }
        // pass the request along the filter chain
        chain.doFilter(request, response);
      

      }

      public void destroy() { //we can close resources here }

    }

      1package com.journaldev.servlet.filters;
      2
      3import java.io.IOException;
      4
      5import javax.servlet.Filter;
      6import javax.servlet.FilterChain;
      7import javax.servlet.FilterConfig;
      8import javax.servlet.ServletContext;
      9import javax.servlet.ServletException;
     10import javax.servlet.ServletRequest;
     11import javax.servlet.ServletResponse;
     12import javax.servlet.annotation.WebFilter;
     13import javax.servlet.http.HttpServletRequest;
     14import javax.servlet.http.HttpServletResponse;
     15import javax.servlet.http.HttpSession;
     16
     17@WebFilter("/AuthenticationFilter")
     18public class AuthenticationFilter implements Filter {
     19
     20	private ServletContext context;
     21
     22	public void init(FilterConfig fConfig) throws ServletException {
     23		this.context = fConfig.getServletContext();
     24		this.context.log("AuthenticationFilter initialized");
     25	}
     26
     27	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
     28
     29		HttpServletRequest req = (HttpServletRequest) request;
     30		HttpServletResponse res = (HttpServletResponse) response;
     31
     32		String uri = req.getRequestURI();
     33		this.context.log("Requested Resource::"+uri);
     34
     35		HttpSession session = req.getSession(false);
     36
     37		if(session == null && !(uri.endsWith("html") || uri.endsWith("LoginServlet"))){
     38			this.context.log("Unauthorized access request");
     39			res.sendRedirect("login.html");
     40		}else{
     41			// pass the request along the filter chain
     42			chain.doFilter(request, response);
     43		}
     44
     45
     46	}
     47
     48	public void destroy() {
     49		//close any resources here
     50	}
     51
     52}
     53```Notice that we are not authenticating any HTML page or LoginServlet. Now we will configure these filters mapping in the web.xml file.```
     54<?xml version="1.0" encoding="UTF-8"?>
     55<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://java.sun.com/xml/ns/javaee" xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
     56 <display-name>ServletFilterExample</display-name>
     57 <welcome-file-list>
     58   <welcome-file>login.html</welcome-file>
     59 </welcome-file-list>
     60
     61 <filter>
     62   <filter-name>RequestLoggingFilter</filter-name>
     63   <filter-class>com.journaldev.servlet.filters.RequestLoggingFilter</filter-class>
     64 </filter>
     65 <filter>
     66   <filter-name>AuthenticationFilter</filter-name>
     67   <filter-class>com.journaldev.servlet.filters.AuthenticationFilter</filter-class>
     68 </filter>
     69
     70 <filter-mapping>
     71   <filter-name>RequestLoggingFilter</filter-name>
     72   <url-pattern>/*</url-pattern>
     73   <dispatcher>REQUEST</dispatcher>
     74 </filter-mapping>
     75 <filter-mapping>
     76   <filter-name>AuthenticationFilter</filter-name>
     77   <url-pattern>/*</url-pattern>
     78 </filter-mapping>
     79</web-app>
     80```Now when we will run our application, we will get response pages like below images. [![Servlet Filter Example](spaces/2013/08/Servlet-Filter-Login-450x141.png)](https://journaldev.nyc3.digitaloceanspaces.com/2013/08/Servlet-Filter-Login.png) [![Servlet Filter, Java Filter](spaces/2013/08/Servlet-Filter-Login-Success-450x229.png)](https://journaldev.nyc3.digitaloceanspaces.com/2013/08/Servlet-Filter-Login-Success.png) [![Servlet Filter Tutorial, Java Servlet Filter](spaces/2013/08/Servlet-Filter-Checkout-450x181.png)](https://journaldev.nyc3.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.```
     81Aug 13, 2013 1:06:07 AM org.apache.catalina.core.ApplicationContext log
     82INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,B7275762B8D23121152B1270D6EB240A}
     83Aug 13, 2013 1:06:07 AM org.apache.catalina.core.ApplicationContext log
     84INFO: Requested Resource::/ServletFilterExample/
     85Aug 13, 2013 1:06:07 AM org.apache.catalina.core.ApplicationContext log
     86INFO: Unauthorized access request
     87Aug 13, 2013 1:06:07 AM org.apache.catalina.core.ApplicationContext log
     88INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,B7275762B8D23121152B1270D6EB240A}
     89Aug 13, 2013 1:06:07 AM org.apache.catalina.core.ApplicationContext log
     90INFO: Requested Resource::/ServletFilterExample/login.html
     91Aug 13, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log
     92INFO: 0:0:0:0:0:0:0:1%0::Request Params::{pwd=password}
     93Aug 13, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log
     94INFO: 0:0:0:0:0:0:0:1%0::Request Params::{user=admin}
     95Aug 13, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log
     96INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,B7275762B8D23121152B1270D6EB240A}
     97Aug 13, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log
     98INFO: Requested Resource::/ServletFilterExample/LoginServlet
     99Aug 13, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log
    100INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56}
    101Aug 13, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log
    102INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin}
    103Aug 13, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log
    104INFO: Requested Resource::/ServletFilterExample/LoginSuccess.jsp
    105Aug 13, 2013 1:06:52 AM org.apache.catalina.core.ApplicationContext log
    106INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56}
    107Aug 13, 2013 1:06:52 AM org.apache.catalina.core.ApplicationContext log
    108INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin}
    109Aug 13, 2013 1:06:52 AM org.apache.catalina.core.ApplicationContext log
    110INFO: Requested Resource::/ServletFilterExample/CheckoutPage.jsp
    111Aug 13, 2013 1:07:00 AM org.apache.catalina.core.ApplicationContext log
    112INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56}
    113Aug 13, 2013 1:07:00 AM org.apache.catalina.core.ApplicationContext log
    114INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin}
    115Aug 13, 2013 1:07:00 AM org.apache.catalina.core.ApplicationContext log
    116INFO: Requested Resource::/ServletFilterExample/LogoutServlet
    117JSESSIONID=8BDF777933194EDCAC1D8F1B73633C56
    118User=Pankaj
    119Aug 13, 2013 1:07:00 AM org.apache.catalina.core.ApplicationContext log
    120INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56}
    121Aug 13, 2013 1:07:00 AM org.apache.catalina.core.ApplicationContext log
    122INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin}
    123Aug 13, 2013 1:07:00 AM org.apache.catalina.core.ApplicationContext log
    124INFO: Requested Resource::/ServletFilterExample/login.html
    125Aug 13, 2013 1:07:06 AM org.apache.catalina.core.ApplicationContext log
    126INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56}
    127Aug 13, 2013 1:07:07 AM org.apache.catalina.core.ApplicationContext log
    128INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin}
    129Aug 13, 2013 1:07:07 AM org.apache.catalina.core.ApplicationContext log
    130INFO: Requested Resource::/ServletFilterExample/LoginSuccess.jsp
    131Aug 13, 2013 1:07:07 AM org.apache.catalina.core.ApplicationContext log
    132INFO: Unauthorized access request
    133Aug 13, 2013 1:07:07 AM org.apache.catalina.core.ApplicationContext log
    134INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56}
    135Aug 13, 2013 1:07:07 AM org.apache.catalina.core.ApplicationContext log
    136INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin}
    137Aug 13, 2013 1:07:07 AM org.apache.catalina.core.ApplicationContext log
    138INFO: Requested Resource::/ServletFilterExample/login.html
    139```
    

它是Java EE网页应用程序的重要功能之一,我们应该使用它用于各种服务器执行的常见任务。在未来的帖子中,我们将看看服务器收听器和cookie。 更新:收到大量可下载项目的请求后,我已将其附加到帖子中,从下面链接下载。

下载服务器过滤器示例项目

请参阅关于 [Servlet Listener]系列的下一篇文章(/community/tutorials/servletcontextlistener-servlet-listener-example“Servlet Listener Example – ServletContextListener, HttpSessionListener and ServletRequestListener”)Update Struts 2使用Servlet Filter来拦截客户端请求并将其传送到适当的类行动,这些被称为Struts 2 Interceptors。

Published At
Categories with 技术
Tagged with
comments powered by Disqus