JSP Filters
Filters in both JSP and Servlets are Java classes.
Filters can dynamically intercept requests and responses to transform or use the information contained in the request or response.
One or more filters can be attached to a Servlet or a group of Servlets. Filters can also be attached to JavaServer Pages (JSP) files and HTML pages.
Filters are Java classes that can be used in Servlet programming to achieve the following purposes:
- Intercept client requests before they access backend resources.
- Process server responses before they are sent back to the client.
According to the specification, various types of filters are suggested:
- Authentication Filters.
- Data compression Filters.
- Encryption Filters.
- Filters that trigger resource access events.
- Image Conversion Filters.
- Logging and Auditing Filters.
- MIME-TYPE Chain Filters.
- Tokenizing Filters.
- XSL/T Filters, for transforming XML content.
Filters are declared via XML tags in the web deployment descriptor (web.xml) and then mapped to Servlet names or URL patterns in your application's deployment descriptor.
When the Web container starts a web application, it creates an instance for each filter declared in the deployment descriptor.
The execution order of Filters is consistent with the configuration order in the web.xml file. Generally, Filters are configured before all Servlets.
Servlet Filter Methods
A filter is a Java class that implements the javax.servlet.Filter interface. The javax.servlet.Filter interface defines three methods:
| Number | Method & Description |
|---|---|
| 1 |
public void doFilter (ServletRequest, ServletResponse, FilterChain)This method performs the actual filtering work. When a client request matches the URL set for the filter, the Servlet container first calls the filter's doFilter method. FilterChain is used to access subsequent filters.
|
| 2 |
public void init(FilterConfig filterConfig)When the web application starts, the web server creates an instance of the Filter and calls its init method, reading the web.xml configuration to complete the object's initialization, thereby preparing for subsequent user request interception (the filter object is created only once, and the init method is also executed only once). Developers can obtain the FilterConfig object representing the current filter's configuration information through the parameters of the init method.
|
| 3 |
public void destroy()The Servlet container calls this method before destroying the filter instance. In this method, resources occupied by the Servlet filter are released. |
FilterConfig Usage
The init method of a Filter provides a FilterConfig object.
For example, if the web.xml file is configured as follows:
<filter>
<filter-name>LogFilter</filter-name>
<filter-class>com.tutorial.test.LogFilter</filter-class>
<init-param>
<param-name>Site</param-name>
<param-value>Tutorial</param-value>
</init-param>
</filter>
Use the FilterConfig object in the init method to get parameters:
public void init(FilterConfig config) throws ServletException {
// Get initialization parameters
String site = config.getInitParameter("Site");
// Print initialization parameters
System.out.println("Website Name: " + site);
}
JSP Filter Example
Below is an example of a Servlet filter that will output the website name and address. This example gives you a basic understanding of Servlet filters. You can use the same concept to write more complex filter applications:
//Import required java libraries
import javax.servlet.*;
import java.util.*;
//Implement Filter class
public class LogFilter implements Filter {
public void init(FilterConfig config) throws ServletException {
// Get initialization parameters
String site = config.getInitParameter("Site");
// Print initialization parameters
System.out.println("Website Name: " + site);
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException, ServletException {
// Print site name
System.out.println("Site URL: ");
// Pass the request back to the filter chain
chain.doFilter(request,response);
}
public void destroy( ){
/* Called before the Filter instance is removed from service by the Web container */
}
}
The DisplayHeader.java file code is as follows:
//Import required java libraries
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/DisplayHeader")
//Extend HttpServlet class
public class DisplayHeader extends HttpServlet {
// Method to handle GET method request
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
// Set response content type
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String title = "HTTP Header Request Example - Tutorial Example";
String docType =
"<!DOCTYPE html> n";
out.println(docType +
"<html>n" +
"<head><meta charset="utf-8"><title>" + title + "</title></head>n"+
"<body bgcolor="#f0f0f0">n" +
"<h1 align="center">" + title + "</h1>n" +
"<table width="100%" border="1" align="center">n" +
"<tr bgcolor="#949494">n" +
"<th>Header Name</th><th>Header Value</th>n"+
"</tr>n");
Enumeration headerNames = request.getHeaderNames();
while(headerNames.hasMoreElements()) {
String paramName = (String)headerNames.nextElement();
out.print("<tr><td>" + paramName + "</td>n");
String paramValue = request.getHeader(paramName);
out.println("<td> " + paramValue + "</td></tr>n");
}
out.println("</table>n</body></html>");
}
// Method to handle POST method request
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
Servlet Filter Mapping in web.xml
Define a filter and then map it to a URL or Servlet, which is roughly the same as defining a Servlet and then mapping it to a URL pattern. Create the following entry for the filter tag in the deployment descriptor file web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<filter>
<filter-name>LogFilter</filter-name>
<filter-class>com.tutorial.test.LogFilter</filter-class>
<init-param>
<param-name>Site</param-name>
<param-value>Tutorial</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>LogFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<!-- Class name -->
<servlet-name>DisplayHeader</servlet-name>
<!-- Package -->
<servlet-class>com.tutorial.test.DisplayHeader</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DisplayHeader</servlet-name>
<!-- URL to access -->
<url-pattern>/TomcatTest/DisplayHeader</url-pattern>
</servlet-mapping>
</web-app>
The above filter applies to all Servlets because we specified /* in the configuration. If you only want to apply the filter to a few Servlets, you can specify a specific Servlet path.
Now try to invoke any Servlet in the usual way, and you will see the generated log in the web server. You can also use the Log4J logger to record the above log to a separate file.
Next, we visit this example address http://localhost:8080/TomcatTest/DisplayHeader, and then look at the output content in the console, as shown below:
Using Multiple Filters
Web applications can define several different filters for specific purposes. Suppose you define two filters, AuthenFilter and LogFilter. You need to create a different mapping as described below. The rest of the processing is roughly the same as explained above:
<filter>
<filter-name>LogFilter</filter-name>
<filter-class>com.tutorial.test.LogFilter</filter-class>
<init-param>
<param-name>test-param</param-name>
<param-value>Initialization Paramter</param-value>
</init-param>
</filter>
<filter>
<filter-name>AuthenFilter</filter-name>
<filter-class>com.tutorial.test.AuthenFilter</filter-class>
<init-param>
<param-name>test-param</param-name>
<param-value>Initialization Paramter</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>LogFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>AuthenFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Filter Application Order
The order of the <filter-mapping> elements in web.xml determines the order in which the Web container applies filters to Servlets. To reverse the order of filters, you simply need to reverse the order of the <filter-mapping> elements in the web.xml file.
For example, the above example will apply LogFilter first, then AuthenFilter, but the following example will reverse this order:
<filter-mapping>
<filter-name>AuthenFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>LogFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Description of web.xml Configuration Nodes
<filter>Specifies a filter.<filter-name>Used to specify a name for the filter. The content of this element cannot be empty.<filter-class>Element used to specify the fully qualified class name of the filter.<init-param>Element used to specify initialization parameters for the filter. Its child elements<param-name>specify the parameter name, and<param-value>specify the parameter value.- In the filter, you can use the
FilterConfiginterface object to access initialization parameters. <filter-mapping>Element used to set the resources that a Filter is responsible for intercepting. The resources intercepted by a Filter can be specified in two ways: Servlet name and resource access request path.<filter-name>Child element used to set the registered name of the filter. This value must be the name of a filter declared in the<filter>element.<url-pattern>Sets the request path intercepted by the filter (URL pattern associated with the filter).<servlet-name>Specifies the name of the Servlet intercepted by the filter.<dispatcher>Specifies the way in which the resources intercepted by the filter are called by the Servlet container. It can be one of REQUEST, INCLUDE, FORWARD, and ERROR, with REQUEST as the default. Users can set multiple<dispatcher>child elements to specify that the Filter intercepts multiple invocation methods for resources.- Values that can be set for the
<dispatcher>child element and their meanings:- REQUEST: When the user directly accesses the page, the Web container will call the filter. If the target resource is accessed via RequestDispatcher's
include()orforward()method, then the filter will not be called. - INCLUDE: If the target resource is accessed via RequestDispatcher's
include()method, then the filter will be called. Otherwise, the filter will not be called. - FORWARD: If the target resource is accessed via RequestDispatcher's
forward()method, then the filter will be called. Otherwise, the filter will not be called. - ERROR: If the target resource is invoked via the declarative exception handling mechanism, then the filter will be called. Otherwise, the filter will not be called.
- REQUEST: When the user directly accesses the page, the Web container will call the filter. If the target resource is accessed via RequestDispatcher's
Notes
1. Basic Working Principle of Filter
- A Filter program is a Java class that implements a special interface. Similar to a Servlet class, it is also invoked and executed by the Servlet container.
- When a Filter is registered in web.xml to intercept a certain Servlet program, it can decide whether to continue passing the request to the Servlet program, and whether to modify the request and response messages.
- When the Servlet container starts to invoke a certain Servlet program, if it finds that a Filter program has been registered to intercept the Servlet, the container no longer directly calls the Servlet's
servicemethod, but calls the Filter'sdoFiltermethod, and then thedoFiltermethod decides whether to activate theservicemethod. - However, in the
Filter.doFiltermethod, you cannot directly call the Servlet'sservicemethod. Instead, you call theFilterChain.doFiltermethod to activate the target Servlet'sservicemethod. TheFilterChainobject is passed in through the parameters of theFilter.doFiltermethod. - As long as you add certain program code before and after the statement that calls the
FilterChain.doFiltermethod in theFilter.doFiltermethod, you can implement certain special functions before and after the Servlet responds. - If the
FilterChain.doFiltermethod is not called in theFilter.doFiltermethod, the target Servlet'sservicemethod will not be executed. In this way, certain illegal access requests can be blocked through the Filter.
For more content, you can refer to: Introduction to Filter, FilterChain, FilterConfig
YouTip