o7planning

Java Servlet Filter Tutorial with Examples

  1. Introduction
  2. Why need Server-Filter?
  3. What can Servlet-filter do?
  4. Create Project to start with Servlet-Filter
  5. Configuring the runtime environment
  6. The first Servlet-Filter example
  7. Working models of Filter
  8. Init Paramters of Servlet-Filter
  9. Servlet-Filter url-pattern
  10. Servlet-Filter using Annotation
  11. Establishing JDBC connection in the Filter
  12. Java JSP Tutorial

1. Introduction

This document is based on:
  • Eclipse 4.6 NEON

  • Tomcat 8.x

You should have knowledge of Servlet before reading documents on Servlet-Filter, if you are a beginner, you can see the Java Servlet at:

2. Why need Server-Filter?

Situation 1:
Normally, when user requests a web page, a request is sent to the server, it will have to pass through the filter before before reaching the page required, like the illustration below:
Situation 2:
However, there are situations where the user's request do not pass all Filters
Situation 3:
In case that the user requests a page (page 1), this request must pass Filters, in a certain filter, the request are redirected to a different page (page2).
Example situation:
  1. Users submit a request for personal info.
  2. Request will be sent to the Server.
  3. It goes through Filter that records log information.
  4. It goes to Filter to check user logined or not, this filter found that the user is not logined, it will redirect the request of the user to the login page.

3. What can Servlet-filter do?

Sometimes, you believed that Filter only used to redirect the user requests to a different page, or block access to a particular page if the user has no right. Or used to write log information.
In fact, Filter can be used to encoding web pages. For example, set UTF-8 encoding for the page. Opening and closing the connection to the database and preparing JDBC transaction

4. Create Project to start with Servlet-Filter

First we create a WebApp project to work with servlet-filter.
  • File/New/Other...
Enter:
  • Project Name: ServletFilterTutorial
Project has been created:
Create file index.html:
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Home Page</title>
</head>
<body>

  <h2>Servlet-Filter Tutorial</h2>

</body>
</html>

5. Configuring the runtime environment

Right-click on Project and select Properties:
Right-click on Project and select:
  • Run As/Run on Server
OK !, everything was ready to start learning Servlet-Filter.

6. The first Servlet-Filter example

Servlet-Filter is a class that implements javax.servlet.Filter interface. Class LogFilter below records the time and link of the request sent to the WebApp.
LogFilter.java
package org.o7planning.tutorial.servletfilter;

import java.io.IOException;
import java.util.Date;

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 LogFilter implements Filter {

	public LogFilter() {
	}

	@Override
	public void init(FilterConfig fConfig) throws ServletException {
		System.out.println("LogFilter init!");
	}

	@Override
	public void destroy() {
		System.out.println("LogFilter destroy!");
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {

		HttpServletRequest req = (HttpServletRequest) request;

		String servletPath = req.getServletPath();

		System.out.println("#INFO " + new Date() + " - ServletPath :" + servletPath //
				+ ", URL =" + req.getRequestURL());

		// Go to the next element (filter or target) in chain.
		chain.doFilter(request, response);
	}

}
Configure filter in web.xml:
Add the configuration in web.xml:
<!--
  Declaring a filter named logFilter
-->
<filter>
  <filter-name>logFilter</filter-name>
  <filter-class>org.o7planning.tutorial.servletfilter.LogFilter</filter-class>
</filter>

<!--
  Declare the path (of the page) will have the effect of logFilter
 /* for all paths
-->
<filter-mapping>
  <filter-name>logFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns="http://java.sun.com/xml/ns/javaee"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                               http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
   id="WebApp_ID" version="3.0">

<display-name>ServletFilterTutorial</display-name>

<filter>
 <filter-name>logFilter</filter-name>
 <filter-class>org.o7planning.tutorial.servletfilter.LogFilter</filter-class>
</filter>

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



<welcome-file-list>
 <welcome-file>index.html</welcome-file>
 <welcome-file>index.htm</welcome-file>
 <welcome-file>index.jsp</welcome-file>
 <welcome-file>default.html</welcome-file>
 <welcome-file>default.htm</welcome-file>
 <welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
Rerun you web application
You can run the following link in your browser, here are the links to sources that do not exist on your WebApp, but it is still under the effect of LogFilter.
Log information is recorded on the Console screen :
The code allows the request pass Filter to continue to the page requested.
// Allow the request to move forward.
// It can go to the next filter or to the target.
chain.doFilter(request, response);

7. Working models of Filter

When the user sends a request, the target may be a resource or a servlet. Request must be passed through the filter and finally the target. The filter and target is chained together like illustration below:
Use chain.doFilter (request, response)to move the request to the next stage. If the chain.doFilter (request, response) filter is not called, the user's request will not reach the target, it will be stopped at that filter.

8. Init Paramters of Servlet-Filter

Like with Servlet, you can initialize the parameters for Filter. The example below, a Filter do mission of writing log to a file, you can configure in web.xml file name for writing.
Log2Filter.java
package org.o7planning.tutorial.servletfilter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class Log2Filter implements Filter {

	private String logFile;

	public Log2Filter() {
	}

	@Override
	public void init(FilterConfig fConfig) throws ServletException {
		this.logFile = fConfig.getInitParameter("logFile");

		System.out.println("Log File " + logFile);
	}

	@Override
	public void destroy() {
		System.out.println("Log2Filter destroy!");
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {

		if (this.logFile != null) {
			// Write log to file.
			this.logToFile(this.logFile);
		}

		// Go to the next element (filter or target) in chain.
		chain.doFilter(request, response);
	}

	private void logToFile(String fileName) {
		// Write log to file
		System.out.println("Write log to file " + fileName);
	}

}
Add the configuration in web.xml:
<filter>
   <filter-name>log2Filter</filter-name>
   <filter-class>org.o7planning.tutorial.servletfilter.Log2Filter</filter-class>
   <init-param>
       <param-name>logFile</param-name>
       <param-value>AppLog.log</param-value>
   </init-param>
</filter>

<filter-mapping>
   <filter-name>log2Filter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>ServletFilterTutorial</display-name>

<filter>
  <filter-name>logFilter</filter-name>
  <filter-class>org.o7planning.tutorial.servletfilter.LogFilter</filter-class>
</filter>

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


<filter>
  <filter-name>log2Filter</filter-name>
  <filter-class>org.o7planning.tutorial.servletfilter.Log2Filter</filter-class>
  <init-param>
      <param-name>logFile</param-name>
      <param-value>AppLog.log</param-value>
  </init-param>
</filter>

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


<welcome-file-list>
  <welcome-file>index.html</welcome-file>
  <welcome-file>index.htm</welcome-file>
  <welcome-file>index.jsp</welcome-file>
  <welcome-file>default.html</welcome-file>
  <welcome-file>default.htm</welcome-file>
  <welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>

9. Servlet-Filter url-pattern

There are 3 ways you can configure url-pattern for Filter:
URL Pattern
Example
/*
http://example.com/contextPath
/*
http://example.com/contextPath/status/abc
/status/abc/*
http://example.com/contextPath/status/abc
/status/abc/*
http://example.com/contextPath/status/abc/mnp
/status/abc/*
http://example.com/contextPath/status/abc/mnp?date=today
/status/abc/*
http://example.com/contextPath/test/abc/mnp
*.map
http://example.com/contextPath/status/abc.map
*.map
http://example.com/contextPath/status.map?date=today
*.map
http://example.com/contextPath/status/abc.MAP

10. Servlet-Filter using Annotation

The example above, the filter configuration in web.xml, however, with the WebApp version 3 or higher you can use Annotation to configure the Filter .
This example illustrates when users send requests to view a image file (jpg, png or gif), Filter will check image file exists or not, in case that does not exist, filter will redirect the request to a default image file.
First, you copyflower.png & image-not-found.png files into images folder on your WebApp
ImageFilter.java
package org.o7planning.tutorial.servletfilter;

import java.io.File;
import java.io.IOException;

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.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebFilter(urlPatterns = { "*.png", "*.jpg", "*.gif" }, initParams = {
		@WebInitParam(name = "notFoundImage", value = "/images/image-not-found.png") })
public class ImageFilter implements Filter {

	private String notFoundImage;

	public ImageFilter() {
	}

	@Override
	public void init(FilterConfig fConfig) throws ServletException {

		// ==> /images/image-not-found.png
		notFoundImage = fConfig.getInitParameter("notFoundImage");
	}

	@Override
	public void destroy() {
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {

		HttpServletRequest req = (HttpServletRequest) request;

		// ==> /images/path/my-image.png
		// ==> /path1/path2/image.pngs
		String servletPath = req.getServletPath();

		// The absolute path of the WebApp root directory (WebContent).
		String realRootPath = request.getServletContext().getRealPath("");

		// The absolute path of Image.
		String imageRealPath = realRootPath + servletPath;

		System.out.println("imageRealPath = " + imageRealPath);

		File file = new File(imageRealPath);

		// Check image exists.
		if (file.exists()) {

			// Go to the next element (filter or servlet) in chain
			chain.doFilter(request, response);

		} else if (!servletPath.equals(this.notFoundImage)) {

			// Redirect to 'image not found' image.
			HttpServletResponse resp = (HttpServletResponse) response;

			// ==> /ServletFilterTutorial + /images/image-not-found.png
			resp.sendRedirect(req.getContextPath() + this.notFoundImage);

		}

	}

}
Rerun your application and test the following URL:
With links requested image file, however the image file does not exist, it will be redirected to the default image.
In the example above, you can also use the Forward instead of Redirect request to the default image file in case required image file does not exist.
// Redirect:

// ==> /ServletFilterTutorial + /images/image-not-found.png
response.sendRedirect(request.getContextPath()+ this.notFoundImage);

// Forward:

request.getServletContext().getRequestDispatcher(this.notFoundImage).forward(request, response);

11. Establishing JDBC connection in the Filter

You can create a Connection object connect to JDBC in Servlet to handle work with Database. However, you can also create a Connection object connect to JDBC in Filter, and it will take effect with many Servlets. And you can use this Connection throughout the way of request. You can see the illustration below for understandable
ConnectionUtils is the class that creates a Connection object connected to the database, in this document, I do not introduce in detail how to get Connection object.
You can learn about document on JDBC at:
ConnectionUtils.java
package org.o7planning.tutorial.servletfilter.conn;

import java.sql.Connection;

public class ConnectionUtils {

	public static Connection getConnection() {

		// Create a Connection to database.
		Connection conn = null;

		// .....
		return conn;
	}

	public static void closeQuietly(Connection conn) {
		try {
			conn.close();
		} catch (Exception e) {
		}
	}

	public static void rollbackQuietly(Connection conn) {
		try {
			conn.rollback();
		} catch (Exception e) {
		}
	}
}
MyUtils.java
package org.o7planning.tutorial.servletfilter.conn;

import java.sql.Connection;

import javax.servlet.ServletRequest;

public class MyUtils {

	public static final String ATT_NAME = "MY_CONNECTION_ATTRIBUTE";

	// Store Connection to attribute of request
	// Information stored only exists during request
	// until the data is returned to the user browser.
	public static void storeConnection(ServletRequest request, Connection conn) {
		request.setAttribute(ATT_NAME, conn);
	}

	// Get the Connection object has been stored in one attribute of the request.
	public static Connection getStoredConnection(ServletRequest request) {
		Connection conn = (Connection) request.getAttribute(ATT_NAME);
		return conn;
	}
}
I declare url-pattern for JDBCFilter is /*, this filter will work with all the request of users.
JDBCFilter.java
package org.o7planning.tutorial.servletfilter.conn;

import java.io.IOException;
import java.sql.Connection;

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.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;

@WebFilter(urlPatterns = { "/*" })
public class JDBCFilter implements Filter {

	public JDBCFilter() {
	}

	@Override
	public void init(FilterConfig fConfig) throws ServletException {

	}

	@Override
	public void destroy() {

	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {

		HttpServletRequest req = (HttpServletRequest) request;

		// 
		String servletPath = req.getServletPath();

		// Only open Connection for special request.
		// (For example: servlet, jsp, ..)
		// 
		// Avoid open Connection for the common request
		// (For example image, css, javascript,... )
		// 
		if (servletPath.contains("/specialPath1") || servletPath.contains("/specialPath2")) {
			Connection conn = null;
			try {
				// Create a Connection.
				conn = ConnectionUtils.getConnection();
				// Set auto commit = false
				conn.setAutoCommit(false);

				// Store connection in attribute of request.
				MyUtils.storeConnection(request, conn);

				// Go to next element (filter or target) in chain
				chain.doFilter(request, response);

				// Call commit() to commit transaction.
				conn.commit();
			} catch (Exception e) {
				ConnectionUtils.rollbackQuietly(conn);
				throw new ServletException();
			} finally {
				ConnectionUtils.closeQuietly(conn);
			}
		}
		// For common request.
		else {
			// Go to next element (filter or target) in chain.
			chain.doFilter(request, response);
		}

	}

}
At the next filter or in target (servlet, or JSP), you can obtain a Connection object stored in a attribute of the request:
Connection conn = (Connection) request.getAttribute(ATT_NAME);

// Or
Connection conn = MyUtils.getStoredConnection();

12. Java JSP Tutorial

Next, you can learn JSP at: