15 - JSP Filters

15.1 Overview of JSP Filters

JSP Specification provides a concept of filters to intercept the requests before reaching the actual JSP or servlets and similarly can update the response before sending to client.

In other words a filter is used to perform certain logic before and / or after the functionality of a web application.

There can be several scenarios where we can use filters. Some of them can be

a) Only authenticated or a specified requests can access the destination

b) Compressing the data before sending it to client

c) To have a auditing or logging logic.

For any filtering logic, we can write a filter and can map the filter to a url pattern.

You might be thinking that we can have such logic in JSP or servlets also So the answer is YES, you can but there are two design issues-

· You have to write repetitive filtering logic that needs to be applied on multiple resource.

· Having filtering logic in separate component keeps the design good and we will have right logic in right component.

· Filters are configured in deployment descriptors so can be easily plugged in or plugged out without changing the code.

Refer below Diagram which depicts the flow between JSP /Servlets and filters. There can be ‘n’ numbers of filters configured for a JSP or servlet and all filters execute in a chain. Filter 2 will be executed only if Filter 1 passes the request and so on . Once request passes all the filters ,it reaches destination resource.

Once JSP or servlet completes its logic , request goes back to filter N and then Filter N-1.. and so on.

So a typical flow of the request is F1àF2àF3...Fnà Servlet àFnàFn-1..F1

15.2 JSP Filter Interface

JSP Filter class has to implement javax.servlet.Filter interface. Filter interface defines three methods which means classes implements filter interface has to implement these methods.

· void init(FilterConfig)

· doFilter (ServletRequest, ServletResponse, FilterChain)

· public void destroy()

15.3 JSP Filter Life cycle

The life cycle of a JSP filter is managed by a container and consists of implementing the following methods:
init() This method is called only once after instantiation to perform any initialization task.We can define a initialization parameters in wex,xml for filters similar to init-params of servlets.

doFilter() This method is called after the init() method and is called each time a
filter needs to perform any function. This method performs the actual work of a filter, either modifying the request or the response.

destroy() This method is used to perform any cleanup operation before the container removes a filter instance.

15.4 JSP Filter Configuration

JSP Filters are configured in web.xml like below

<filter>
    <filter-name>SampleFilter</filter-name>
    <filter-class>com.sample.jsp.tutorial.SampleFilter</filter-class>
        <init-param>
            <param-name>my-param</param-name>
            <param-value>my-param-value</param-value>
        </init-param>
</filter>
<filter-mapping>
    <filter-name>SampleFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

15.5 JSP Filter Ordering

We can have multiple filters configured for a given destination and all of them will be executed but how a container will decide which filter to execute first?

Order in which filter gets executed depends on the order in which filters are configured in web.xml. For example if there are two Filter1 and Filter2 configured like below

<filter>
    <filter-name>Filter1</filter-name>
    <filter-class>com.sample.jsp.tutorial.Filter1</filter-class>
        <init-param>
            <param-name>my-param</param-name>
            <param-value>my-param-value</param-value>
        </init-param>
</filter>
<filter-mapping>
    <filter-name>Filter1</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
    <filter-name>Filter2</filter-name>
    <filter-class>com.sample.jsp.tutorial.Filter2</filter-class>
        <init-param>
            <param-name>my-param</param-name>
            <param-value>my-param-value</param-value>
        </init-param>
</filter>
<filter-mapping>
    <filter-name>Filter2</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

In above configuration Filter1 and Filter 2 are both configured for url pattern /* (means for all URLs) but since Filter1 is defined before Filter2 , Filter1 will execute first.

15.6 JSP Filter Examples

15.6.1 Write an example to demonstrate JSP filter life cycle.

Solution – To demonstrate the JSP life cycle, let’s define and write one filter which will print some message in filter life cycle methods on server console to see how many times the methods are getting invoked.

a) Define filter in web.xml

<filter>
    <filter-name>SampleFilter</filter-name>
    <filter-class>com.sample.jsp.tutorial.SampleFilter</filter-class>        
</filter>
<filter-mapping>
    <filter-name>SampleFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

b) Write SampleFilter.java

package com.sample.jsp.tutorial;
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;
/**
 * Servlet Filter implementation class SampleFilter
 */
public class SampleFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException
    {
            System.out.println("Filter initialized...");
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
                FilterChain filterChain) throws IOException, ServletException {
            System.out.println("Filter executing...");
            filterChain.doFilter(request, response);
    }
    @Override
    public void destroy()
    {
            System.out.println("Filter Destroyed..");
    }
}
Testing

As soon as web application is deployed, filter will be initialized which we can verify from the message on console.

Access login.jsp by hitting the url http://localhost:8080/jsp-tutorial/login.jsp three times

Then un deploy the web application so filter will be destroyed

Since we mapped /* url pattern with Filter, it will be invoked for all URLs so we tested it with http://localhost:8080/jsp-tutorial/login.jsp but can see the same behaviour with other URL.

In above section, we discussed the order of execution of multiple filter and servlet.

15.6.2 Demonstrate this behaviour with the help of example.

Solution – To demonstrate the order of execution of multiple filters and JSP, lets define two filter FilterA and FilterB and apply it on filter.jsp.

a) Define Filters entries in web.xml

<filter>
<filter-name>FilterA</filter-name>
<filter-class>com.sample.jsp.tutorial.FilterA</filter-class>
</filter>
<filter-mapping>
<filter-name>FilterA</filter-name>
<url-pattern>/filter.jsp</url-pattern>
</filter-mapping>
<filter>
<filter-name>FilterB</filter-name>
<filter-class>com.sample.jsp.tutorial.FilterB</filter-class>
</filter>
<filter-mapping>
<filter-name>FilterB</filter-name>
<url-pattern>/filter.jsp</url-pattern>
</filter-mapping>
<filter>

b) Write Filters code

FilterA

package com.sample.jsp.tutorial;
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 FilterA implements Filter
{
@Override
public void init(FilterConfig filterConfig) throws ServletException
{
System.out.println("Filter A initialized...");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException
{
System.out.println("Filter A executing Before JSP Processing ...");
filterChain.doFilter(request, response);
System.out.println("Filter A executing after JSP Processing...");
}
@Override
public void destroy() {
System.out.println("Filter A Destroyed..");
}
}

FilterB

package com.sample.jsp.tutorial;
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 FilterB implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException
{
System.out.println("Filter B initialized...");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException
{
System.out.println("Filter B executing Before JSP Processing ...");
filterChain.doFilter(request, response);
System.out.println("Filter B executing after JSP Processing...");
}
@Override
public void destroy()
{
System.out.println("Filter B Destroyed..");
}
}

filter.jsp

<html>
<head>
<title> Filter Demo </title>
</head>
<body>
    <strong>
    This is filter Demo !!!
    </strong>
</body>
</html>
Testing

Access filter.jsp by hitting the url http://localhost:8080/jsp-tutorial/filter.jsp and you can see the messages shown in below figure.

This proves “ F1 à F2 à F3 . . . Fn à Servlet à Fn à Fn-1 . . F1 “

15.6.3 – In the above example, what is the significance of filterChain.doFilter() ?

Solution – filterChain.doFilter() invokes the another filter configured in web.xml. Once all the filter is executed, calling of doFilter() invokes the destination resource. Once resource is executed, lines after filterchain.doFilter() get executed in a reverse order.

15.6.4 – how filter can intercept the request

Write and example to show how filter can intercept the request

Solution- To see how filter can modify the request and response, let’s create

a) Create proptected.jsp which will read and display request parameter (with name “name” )

b) Create RequestInterceptorFilter filter which will be –

· Applied on protected.jsp

· grab the value of request parameter “name” and examine if it is blank or not. If the value is blank , filter will respond back with the error message that and will not pass the request to proptected.jsp.

· If value is entered by user , proptected.jsp which will be executed and will respond back with the value

a) Add entry in web.xml

<filter>
    <filter-name>RequestInterceptorFilter</filter-name>
    <filter-class>com.sample.jsp.tutorial.RequestInterceptorFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>RequestInterceptorFilter</filter-name>
    <url-pattern>/Protected.jsp</url-pattern>
</filter-mapping>

b) Create Protected.jsp

<html>
<head>
<title> Protected JSP </title>
</head>
<body>
    <%
    String name = request.getParameter("name");
    %>
<strong> Value Entered by User is :: </strong> <%= name %>
</body>
</html>

c) Write Filter code

package com.sample.jsp.tutorial;
import java.io.IOException;
import java.io.PrintWriter;
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 RequestInterceptorFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("Filter  initialized...");
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain filterChain) throws IOException, ServletException {
        String name = request.getParameter("name");
        if(name==null || name.equals(""))
        {
            PrintWriter writer = response.getWriter();
            String message="Name cannot be blank.( This is the response from Protected Servlet )";
            writer.println(message);
            return;
        }
        filterChain.doFilter(request, response);
    }
    @Override
    public void destroy() {
        System.out.println("Filter  Destroyed..");
    }
}
Testing

Access Protected.jsp by hitting the url http://localhost:8080/jsp-tutorial/Protected.jsp?name

(no passing any value in name query parameter)

Access Protected.jsp by hitting the url http://localhost:8080/jsp-tutorial/Protected.jsp?name=test

(passing value of name parameter )

This way we can intercept the request and allow request to reach JSP or servlet only if it passes certain criteria.

Similarly we can have a generic logic in filter which can be applied to multiple servlets and we need not to repeat the logic at several places.

15.6.5 Write a filter example to read all the init parameters and display them on screen

Solution- Define a filter with two init params which filter will read and display. In filter we can read the init parameter through FilterConfig.

Servlet has a convenient method getServletConfig() available but in filter there is no such method available.

Filters provides FilterConfig object in initialization method so we can define a instance variable and map it to the one passed in init() method. Refer highlighted section in below code for more details.

a) Add entry in web.xml

<filter>
    <filter-name>DisplayInitParamFilter</filter-name>
    <filter-class>com.sample.jsp.tutorial.DisplayInitParamFilter</filter-class>
    <init-param>
        <param-name>param1</param-name>
        <param-value>value1</param-value>
    </init-param>
    <init-param>
        <param-name>param2</param-name>
        <param-value>Value2</param-value>
    </init-param>
    </filter>
<filter-mapping>
    <filter-name>DisplayInitParamFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

b) Write Filter Code

package com.sample.jsp.tutorial;
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;
public class DisplayInitParamFilter implements Filter {
private FilterConfig filterConfig=null;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
    System.out.println("Filter  initialized...");
    this.filterConfig = filterConfig;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
        FilterChain filterChain) throws IOException, ServletException {
Enumeration<String> initParams= filterConfig.getInitParameterNames();
StringBuffer buffer = new StringBuffer();
while(initParams.hasMoreElements())
{
    String initParamName = initParams.nextElement();
    String initParamValue =filterConfig.getInitParameter(initParamName);
    buffer.append(initParamName+"::" + initParamValue);
}
PrintWriter writer = response.getWriter();
writer.println(buffer.toString());
}
@Override
public void destroy() {
    System.out.println("Filter  Destroyed..");
}
}

Testing

Access login.jsp by hitting the url http://localhost:8080/jsp-tutorial/login.jsp

Like us on Facebook