I. Basic Working Principle of Filter

  • 1. A Filter program is a Java class that implements a special interface. Similar to a Servlet, it is also invoked and executed by the Servlet container.
  • 2. When a Filter is registered in web.xml to intercept a Servlet program, it can decide whether to continue passing the request to the Servlet program, and whether to modify the request and response messages.
  • 3. When the Servlet container begins to invoke a Servlet program, if it finds that a Filter program has been registered to intercept this Servlet, the container no longer directly calls the Servlet's service method. Instead, it calls the Filter's doFilter method, which then decides whether to activate the service method.
  • 4. However, in the Filter.doFilter method, you cannot directly call the Servlet's service method. Instead, you call the FilterChain.doFilter method to activate the target Servlet's service method. The FilterChain object is passed in through the parameters of the Filter.doFilter method.
  • 5. As long as you add some program code before and after the statement that calls FilterChain.doFilter in the Filter.doFilter method, you can implement certain special functions before and after the Servlet responds.
  • 6. If the FilterChain.doFilter method is not called in the Filter.doFilter method, the target Servlet's service method will not be executed. In this way, the Filter can block certain illegal access requests.

II. Filter Chain

  • 1. Multiple Filter programs can be registered in a Web application, and each Filter program can intercept one or a group of Servlet programs. If multiple Filter programs can intercept the access process of a certain Servlet program, when an access request for that Servlet arrives, the Web container will combine these multiple Filter programs into a Filter chain (also called a filter chain).
  • 2. The interception order of the Filters in the Filter chain is the same as their mapping order in the web.xml file. Calling the FilterChain.doFilter method in the previous Filter's doFilter method will activate the next Filter's doFilter method, and the FilterChain.doFilter method called in the last Filter's doFilter method will activate the target Servlet's service method.
  • 3. As long as any Filter in the Filter chain does not call the FilterChain.doFilter method, the target Servlet's service method will not be executed.

III. Filter Interface

A Filter program is a Java class, and this class must implement the Filter interface. The javax.servlet.Filter interface defines three methods: init, doFilter, and destroy.

1. init Method

  • (1) When the Web application starts, the Web server (Web container) will create an instance object for each registered Filter based on the configuration information in its web.xml file, and store it in memory.
  • (2) After the Web container creates the Filter instance object, it will immediately call the init method of that Filter object. The init method is executed only once in the Filter's lifecycle. When the Web container calls the init method, it passes a FilterConfig object that contains the Filter's configuration and runtime environment information.

    public voic init(FilterConfig filterConfig) throws ServletException
  • (3) Developers can perform initialization functions similar to constructors in the init method. Note that if the initialization code needs to use the FilterConfig object, this code can only be written in the init method, not in the constructor (since the init method has not been called yet, the FilterConfig object has not been created, and using it would certainly cause an error).

2. doFilter Method

When a Filter object is able to intercept access requests, the Servlet container will call the Filter object's doFilter method.

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException.ServletException

Among them, the parameters request and response are the request and response objects passed by the Web container or the previous Filter in the Filter chain; the parameter chain is the object representing the current Filter chain.

3. destroy Method

This method is called before the Web container unloads the Filter object, and it is also executed only once. It can perform the opposite function of the init method, releasing resources opened by the Filter object, such as closing database connections and IO streams.


IV. FilterChain Interface

This interface is used to define the methods that a Filter chain object should provide externally. This interface defines only one doFilter method.

public void doFilter(ServletRequest request, ServletResponse response) throws java.io.IOException.ServletException

The doFilter method of the FilterChain interface is used to notify the Web container to pass the request to the next Filter in the Filter chain for processing. If the current Filter object calling this method is the last Filter in the Filter chain, the request will be handed over to the target Servlet program for processing.


V. FilterConfig Interface

  • 1. Like ordinary Servlet programs, Filter programs may also need to access the Servlet container. The Servlet specification encapsulates the ServletContext object and the Filter's configuration parameter information into an object called FilterConfig.
  • 2. The FilterConfig interface is used to define the methods that a FilterConfig object should provide externally, so that in a Filter program, these methods can be called to obtain the ServletContext object, as well as the friendly name and initialization parameters set for the Filter in the web.xml file.
  • 3. Methods defined by the FilterConfig interface:

    • getFilterName method: returns the value set in the <filter-name> element.

    • getServletContext method: returns a reference to the ServletContext object wrapped in the FilterConfig object.

    • getInitParameter method: used to return the value of an initialization parameter with a specified name set for the Filter in the web.xml file.

    • getInitParameterNames method: returns an Enumeration collection object.


VI. Registration and Mapping of Filter

1. Registering a Filter

A <filter> element is used to register a Filter. Among them, the <filter-name> element is required, the <filter-class> element is also required, and the <init-param> element is optional; there can be multiple <init-param> elements.

<filter>
    <filter-name>FirstFilter</filter-name>
    <filter-class>FirstFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>GB2312</param-value>
    </init-param>
</filter>

2. Mapping a Filter

The <filter-mapping> element is used to set the resources that a Filter is responsible for intercepting. The resources intercepted by a Filter can be specified in two ways: the resource's access request path and the Servlet name.

First method: specify the resource's access path

<filter-mapping>
    <filter-name>FirstFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

The setting of the access path in the <url-pattern> element follows the Servlet URL mapping specification.

  • /*Indicates that all access requests are intercepted.
  • /filter/*Indicates intercepting all access requests under the filter directory, such as: http://localhost:8888/testFilter_001/filter/xxxxxx.
  • /test.htmlIndicates intercepting access requests with test.html as the resource name in the root directory; the access link will only be: http://localhost:8888/test.html.

Second method: specify the Servlet name

<filter-mapping>
    <filter-name>FirstFilter</filter-name>
    <servlet-name>default></servlet-name>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>REQUEST</dispatcher>
</filter-mapping>

(1) The <servlet-name> element and the <url-pattern> element are mutually exclusive; their value is the registered name of a Servlet in the web.xml file.

(2) The <dispatcher> element has four possible values: REQUEST, INCLUDE, FORWARD, ERROR, corresponding respectively to the four ways the Servlet container invokes resources:

  • Called through normal access requests;

  • Called through the RequestDispatcher.include method;

  • Called through the RequestDispatcher.forward method;

  • Called as an error response resource.

If the <dispatcher> child element is not set, it is equivalent to the REQUEST case. Multiple <dispatcher> child elements can also be set to specify that the Filter intercepts multiple invocation methods of the resource.


VII. Filter Program Example

FitstFilter.java

import java.io.IOException; import java.io.PrintWriter; import java.util.Enumeration; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; public class FirstFilter implements Filter { private FilterConfig filterConfig = null; String paramValue = null; @Override public void init(FilterConfig filterConfig) throws ServletException { this.filterConfig = filterConfig; paramValue = filterConfig.getInitParameter("encoding"); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("begin headers-------------------"); Enumeration<?> headerNames = ((HttpServletRequest)request).getHeaderNames(); while(headerNames.hasMoreElements()) { String headerName = (String)headerNames.nextElement(); System.out.println(headerName + ": " + ((HttpServletRequest)request).getHeader(headerName)); } System.out.println("end headers-------------------"); //Write response content before invoking the target response.setContentType("text/html; charset=gb2312"); PrintWriter out = response.getWriter(); out.println("The IP address is:" + request.getRemoteHost() + "<br>"); chain.doFilter(request, response); //Write response content after the target returns out.println("<br>The value of the initialization parameter named encoding is:" + paramValue); out.println("<br>The real path of the current Web application is:" + filterConfig.getServletContext().getRealPath("/")); //out.println("<br>test.html file has been modified!"); } @Override public void destroy() { this.filterConfig = null; } }

web.xml

<filter> <filter-name>FirstFilter</filter-name> <filter-class>FirstFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>GB2312</param-value> </init-param> </filter> <filter-mapping> <filter-name>FirstFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>

test.html (located in the filter directory under the WebContent path)

<html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body>This is the original content of the test.html page!</body> </html>

Access:http://localhost:8888/testFilter_001/filter/test.html

Article source: https://my.oschina.net/u/1171518/blog/265467