Servlet Writing Filters
\\n\\nServlet filters can dynamically intercept requests and responses to transform or use the information contained within them.
\\n\\nOne or more Servlet filters can be attached to a Servlet or a group of Servlets. Servlet filters can also be attached to JavaServer Pages (JSP) files and HTML pages. All attached Servlet filters are invoked before calling the Servlet.
\\n\\nServlet filters are Java classes that can be used in Servlet programming to achieve the following purposes:
\\n\\n- \\n
- Intercept client requests before they access backend resources. \\n
- Process server responses before they are sent back to the client. \\n
According to the specification, various types of filters are recommended:
\\n\\n- \\n
- Authentication Filters. \\n
- Data compression Filters. \\n
- Encryption Filters. \\n
- Filters that trigger resource access events. \\n
- Image Conversion Filters. \\n
- Logging and Auditing Filters. \\n
- MIME-TYPE Chain Filters. \\n
- Tokenizing Filters. \\n
- XSL/T Filters, for transforming XML content. \\n
Filters are declared using XML tags in the web deployment descriptor (web.xml) and then mapped to Servlet names or URL patterns in your application's deployment descriptor.
\\n\\nWhen the Web container starts a web application, it creates an instance for each filter declared in the deployment descriptor.
\\n\\nThe execution order of Filters is consistent with their configuration order in the web.xml file. Generally, Filters are configured before all Servlets.
\\n\\nServlet Filter Methods
\\n\\nA filter is a Java class that implements the javax.servlet.Filter interface. The javax.servlet.Filter interface defines three methods:
| Number | \\nMethod & Description | \\n
|---|---|
| 1 | \\n\\n
This method performs the actual filtering operation. When a client request matches the URL set by the filter, the Servlet container first calls the filter's | \\n
| 2 | \\n\\n
When the web application starts, the web server creates an instance of the Filter and calls its | \\n
| 3 | \\n\\n
The Servlet container calls this method before destroying the filter instance. In this method, resources occupied by the Servlet filter are released. \\n | \\n
FilterConfig Usage
\\n\\nThe init method of a Filter provides a FilterConfig object.
For example, if the web.xml file is configured as follows:
\\n\\n<filter>\\n <filter-name>LogFilter</filter-name>\\n <filter-class>com.tutorial.test.LogFilter</filter-class>\\n <init-param>\\n <param-name>Site</param-name>\\n <param-value></param-value>\\n </init-param>\\n</filter>\\n\\nUse the FilterConfig object in the init method to get the parameter:
public void init(FilterConfig config) throws ServletException {\\n // Get initialization parameters\\n String site = config.getInitParameter("Site"); \\n // Output initialization parameters\\n System.out.println("Site Name: " + site); \\n}\\n\\nServlet Filter Example
\\n\\nHere is an example of a Servlet filter that outputs 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:
\\n\\npackage com.tutorial.test;\\n\\n//Import required java libraries\\nimport javax.servlet.*;\\nimport java.util.*;\\n\\n//Implement Filter class\\npublic class LogFilter implements Filter {\\n public void init(FilterConfig config) throws ServletException {\\n // Get initialization parameters\\n String site = config.getInitParameter("Site"); \\n\\n // Output initialization parameters\\n System.out.println("Site Name: " + site); \\n }\\n public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException, ServletException {\\n\\n // Output site name\\n System.out.println("Site URL: https://example.com");\\n\\n // Pass the request back to the filter chain\\n chain.doFilter(request,response);\\n }\\n public void destroy( ){\\n /* Called before the Filter instance is removed from service by the web container */\\n }\\n}\\n\\nHere we use the previously mentioned DisplayHeader.java as an example:
//Import required java libraries\\nimport java.io.IOException;\\nimport java.io.PrintWriter;\\nimport java.util.Enumeration;\\n\\nimport javax.servlet.ServletException;\\nimport javax.servlet.annotation.WebServlet;\\nimport javax.servlet.http.HttpServlet;\\nimport javax.servlet.http.HttpServletRequest;\\nimport javax.servlet.http.HttpServletResponse;\\n\\n@WebServlet("/DisplayHeader")\\n\\n//Extend HttpServlet class\\npublic class DisplayHeader extends HttpServlet {\\n\\n // Method to handle GET method requests\\n public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException\\n {\\n // Set response content type\\n response.setContentType("text/html;charset=UTF-8");\\n\\n PrintWriter out = response.getWriter();\\n String title = "HTTP Header Request instance - Instance";\\n String docType =\\n "<!DOCTYPE html> n";\\n out.println(docType +\\n "<html>n" +\\n "<head><meta charset="utf-8"><title>" + title + "</title></head>n"+\\n "<body bgcolor="#f0f0f0">n" +\\n "<h1 align="center">" + title + "</h1>n" +\\n "<table width="100%" border="1" align="center">n" +\\n "<tr bgcolor="#949494">n" +\\n "<th>Header Name</th><th>Header Value</th>n"+\\n "</tr>n");\\n\\n Enumeration headerNames = request.getHeaderNames();\\n\\n while(headerNames.hasMoreElements()) {\\n String paramName = (String)headerNames.nextElement();\\n out.print("<tr><td>" + paramName + "</td>n");\\n String paramValue = request.getHeader(paramName);\\n out.println("<td> " + paramValue + "</td></tr>n");\\n }\\n out.println("</table>n</body></html>");\\n }\\n // Method to handle POST method requests\\n public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {\\n doGet(request, response);\\n }\\n}\\n\\nServlet Filter Mapping in web.xml
\\n\\nDefining a filter and then mapping it to a URL or Servlet 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"?> \\n<web-app> \\n<filter>\\n <filter-name>LogFilter</filter-name>\\n <filter-class>com.tutorial.test.LogFilter</filter-class>\\n <init-param>\\n <param-name>Site</param-name>\\n <param-value></param-value>\\n </init-param>\\n</filter>\\n<filter-mapping>\\n <filter-name>LogFilter</filter-name>\\n <url-pattern>/*</url-pattern>\\n</filter-mapping>\\n<servlet> \\n <!-- Class name --> \\n <servlet-name>DisplayHeader</servlet-name> \\n <!-- Package where it is located --> \\n <servlet-class>com.tutorial.test.DisplayHeader</servlet-class> \\n</servlet> \\n<servlet-mapping> \\n <servlet-name>DisplayHeader</servlet-name> \\n <!-- URL accessed --> \\n <url-pattern>/TomcatTest/DisplayHeader</url-pattern> \\n</servlet-mapping> \\n</web-app>\\n\\nThe 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 calling any Servlet in the usual way, and you will see the log generated in the Web server. You can also use a Log4J logger to record the above log to a separate file.
\\n\\nNext, we visit the example address http://localhost:8080/TomcatTest/DisplayHeader, and then look at the output content in the console, as shown below:
Using Multiple Filters
\\n\\nWeb 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>\\n <filter-name>LogFilter</filter-name>\\n <filter-class>com.tutorial.test.LogFilter</filter-class>\\n <init-param>\\n <param-name>test-param</param-name>\\n <param-value>Initialization Paramter</param-value>\\n </init-param>\\n</filter>\\n\\n<filter>\\n <filter-name>AuthenFilter</filter-name>\\n <filter-class>com.tutorial.test.AuthenFilter</filter-class>\\n <init-param>\\n <param-name>test-param</param-name>\\n <param-value>Initialization Paramter</param-value>\\n </init-param>\\n</filter>\\n\\n<filter-mapping>\\n <filter-name>LogFilter</filter-name>\\n <url-pattern>/*</url-pattern>\\n</filter-mapping>\\n\\n<filter-mapping>\\n <filter-name>AuthenFilter</filter-name>\\n <url-pattern>/*</url-pattern>\\n</filter-mapping>\\n\\nOrder of Filter Application
\\n\\nThe order of <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, and then AuthenFilter. However, the following example will reverse this order:
<filter-mapping>\\n <filter-name>AuthenFilter</filter-name>\\n <url-pattern>/*</url-pattern>\\n</filter-mapping>\\n\\n<filter-mapping>\\n <filter-name>LogFilter</filter-name>\\n <url-pattern>/*</url-pattern>\\n</filter-mapping>\\n\\nDescription of web.xml Configuration Nodes
\\n\\n- \\n
<filter>Specifies a filter. \\n <filter-name>Used to specify a name for the filter. The content of this element cannot be empty. \\n <filter-class>Element used to specify the fully qualified class name of the filter. \\n <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. \\n - In the filter, you can use the
FilterConfiginterface object to access initialization parameters. \\n <filter-mapping>Element used to set the resources that a Filter is responsible for intercepting. A Filter intercepts resources in two ways: Servlet name and resource access request path. \\n <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. \\n <url-pattern>Sets the request path intercepted by the filter (the URL pattern associated with the filter). \\n <servlet-name>Specifies the name of the Servlet intercepted by the filter. \\n <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. The default is REQUEST. Users can set multiple<dispatcher>child elements to specify that the Filter intercepts multiple invocation methods for resources. \\n - Values that can be set for the
<dispatcher>child element and their meanings:\\n- \\n
- REQUEST: When a user directly accesses a page, the Web container will invoke the filter. If the target resource is accessed via RequestDispatcher's
include()orforward()method, then the filter will not be invoked. \\n - INCLUDE: If the target resource is accessed via RequestDispatcher's
include()method, then the filter will be invoked. Otherwise, the filter will not be invoked. \\n - FORWARD: If the target resource is accessed via RequestDispatcher's
forward()method, then the filter will be invoked. Otherwise, the filter will not be invoked. \\n - ERROR: If the target resource is invoked through a declarative exception handling mechanism, then the filter will be invoked. Otherwise, the filter will not be invoked. \\n
\\n - REQUEST: When a user directly accesses a page, the Web container will invoke the filter. If the target resource is accessed via RequestDispatcher's
Note: In a filter, we can obtain form parameter information using the request object in the doFilter() method. For example, we can get the username and password from the request for logical processing, and also use the response to respond to the user. For instance, if the username verification fails, we can prevent the user from accessing web resources and output a prompt to the browser, telling the user that the username or password is incorrect, etc.
public void doFilter(ServletRequest req, ServletResponse resp,\\nFilterChain chain) throws IOException, ServletException {\\n\\n //Get request information(During testing, name can be added to the URL via GET method)\\n //http://localhost:8080/servlet_demo/helloword?name=123\\n String name = req.getParameter("name");\\n\\n // Filter core code logic\\n System.out.println("Filter retrieves request parameters:"+name);\\n System.out.println("Second filter executes--Site NameοΌexample.com");\\n\\n if("123".equals(name)){\\n // Pass the request back to the filter chain\\n chain.doFilter(req, resp);\\n }else{\\n //Set return content type\\n resp.setContentType("text/html;charset=GBK");\\n\\n //Output response information on the page\\n PrintWriter out = resp.getWriter();\\n out.print("<b>nameIncorrect, request intercepted, cannot access web resources</b>");\\n System.out.println("nameIncorrect, request intercepted, cannot access web resources");\\n }\\n}\\n
YouTip