Java Servlet Filter

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?

Bạn đang đọc: Java Servlet 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








Home Page



  

Servlet-Filter Tutorial

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:




  logFilter
  org.o7planning.tutorial.servletfilter.LogFilter




  logFilter
  /*

web.xml





ServletFilterTutorial


 logFilter
 org.o7planning.tutorial.servletfilter.LogFilter



 logFilter
 /*





 index.html
 index.htm
 index.jsp
 default.html
 default.htm
 default.jsp


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 màn hình hiển thị :

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:



   log2Filter
   org.o7planning.tutorial.servletfilter.Log2Filter
   
       logFile
       AppLog.log
   



   log2Filter
   /*

web.xml




ServletFilterTutorial


  logFilter
  org.o7planning.tutorial.servletfilter.LogFilter



  logFilter
  /*




  log2Filter
  org.o7planning.tutorial.servletfilter.Log2Filter
  
      logFile
      AppLog.log
  



  log2Filter
  /*

 



  index.html
  index.htm
  index.jsp
  default.html
  default.htm
  default.jsp


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
http://example.com/contextPath/status/abc/mnp
http://example.com/contextPath/status/abc/mnp?date=today
http://example.com/contextPath/test/abc/mnp
*.map http://example.com/contextPath/status/abc.map
http://example.com/contextPath/status.map?date=today
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 copy flower.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 link 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 :

  • Java JDBC

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 :