Orion Filter Tutorial, Lesson 1, Your first Filter

In this part of the Orion Filter tutorial, we will build our first Filter, the ever-returning "Hello World" sample!



1 Introduction

    In this part of the tutorial, we will build our first Filter, the ever-returning "Hello World" sample!

    We will begin with going through what a Filter is, and how you can use it. We will then set up a development environment. When that is done, we will create a generic Filter that we will use throughout this tutorial. We will then create a Filter that extends our GenericFilter. After we have created the Filter, we will create a simple JSP page to attach our filter to. We will then configure the usage of our Filter. And finally, we will test it.

2 What is a Filter?

    Filters were implemented in the Servlet 2.3 specification, but many vendors have incorporated some resembling functionality since the dawn of application servers.

    The great advantage of having a standard for Filters is that, as with everything else in this wonderful J2EE world, it will run not only on the application server that you develop it on, but it will also run on any other application server that follows the Servlet 2.3 specification.

    A Filter is basically a component that is invoked when a client request a resource that the Filter is mapped to, such as a URL pattern or a Servlet name. Normally, a filter is used to wrap and manipulate Request, Response or header values before or after the execution of the original request target and do not itself return any response to the client.

    Filters can be configured to act upon a certain request or upon different requests. Filters can also be put into a chain, where a number of Filters can be invoked after each other. Any Filter taking part of such a chain can at any time give control to the next Filter or redirect the request out of the chain. We will look more at creating chains in a later lesson.


    Figure 1: The Filter interface

    A filter uses the javax.servlet.Filter interface, which defines the following 3 methods:


    public void doFilter(final ServletRequest request, final ServletResponse response, FilterChain chain)
    public void init(FilterConfig filterConfig)
    public void destroy()
    Listing 1: The methods defined by the Filter interface

    The container will use the init() method upon initialisation of the Filter to set the FilterConfig for the Filter. It will then call the doFilter() method. When the container is done with the Filter, it will call the destroy() method.

    The developer should make sure that the FilterConfig instance is stored in the Filter when init() method is called, and clear this instance when the Container calls the destroy() method.


    Figure 2: The FilterConfig interface"

    With the use of the FilterConfig we can get hold of any initialising parameters or the Servlet Context. We will look more at utilising the FilterConfig class in lesson 2.


    Figure 3: The FilterChain interface"

    The FilterChain passed into the Filters doFilter() method by the Container is used to invoke the next Filter in the FilterChain. If there is no more Filters to invoke before the target should be accessed, the Container will wrap the target invocation into a DoFilter() method for us, so we will never have to care about if we are at the end of a FilterChain or not.

    Enough already! All this information is available to you in the Servlet 2.3 specification. Lets get some code done!

3 Setting up our development environment

    For simplicity sake, we will use the default-web-app as out test ground for Filters. Feel free to use another web-application if you want to.

    In order to set up our development environment, we will go through the following steps:



    3.1 Step 1: Get the latest version

      Make sure that you've got the latest version of Orion set up.

    3.2 Step 2: Create a 'classes' directory

      Under the directory 'orion/default-web-app/WEB-INF/', make sure that there is a 'classes' directory. If not, create one.

    3.3 Step 3: Create a 'com' directory

      Under the 'orion/default-web-app/WEB-INF/classes/' directory, make sure that there is a 'com' directory. If not, create one.

    3.4 Step 4: Create a 'acme' directory

      Under the 'orion/default-web-app/WEB-INF/classes/com/' directory, make sure that there is an 'acme' directory. If not, create one.

    3.5 Step 5: Create a 'filter' directory

      Under the 'orion/default-web-app/WEB-INF/classes/com/acme/' directory, make sure that there is a 'filter' directory. If not, create one.

    3.6 Step 6: Configure compiler

      Make sure that your compiler has all necessary Orion jars in its classpath, and that it can write to the 'orion/default-web-app/WEB-INF/classes/com/acme/filter/' directory.

    Now we should be all set to write our first Filter.

4 Writing a generic Filter

    Before we write our first Filter, lets create a generic Filter that will hold all needed methods. We can then extend this generic Filter throughout this tutorial.


    Figure 4: The GenericFilter implements the Filter interface and is using the FilterConfig interface."

    This section contains the following steps:



    4.1 Step 1: Create a file named 'GenericFilter.java'

      Start up your editor and start editing a source file with the name 'GenericFilter.java'

    4.2 Step 2: Add import statements

      Start of with the package name and any imports we need, so that your source looks like the following:


      package com.acme.filter;

      import javax.servlet.Filter;
      import javax.servlet.FilterChain;
      import javax.servlet.FilterConfig;
      import javax.servlet.ServletRequest;
      import javax.servlet.ServletResponse;
      import java.io.IOException;
      import javax.servlet.ServletException;
      Listing 5: First part of the GenericFilter class.

      This will make sure that we have the neccessary classes available.

    4.3 Step 3: Add class declaration

      Continue with the following:


      public class GenericFilter implements Filter
      {
      private FilterConfig filterConfig;
      Listing 6: Implementing the Filter.

      Above, we make sure that our class implements the javax.servlet.Filter interface and that each instance of this Filter will have an instance that can hold the FilterConfig given to the class by the Container upon initialisation.

    4.4 Step 4: Add doFilter method

      Add the following method to your source:


      public void doFilter(final ServletRequest request,final ServletResponse response, FilterChain chain)
      throws IOException, ServletException
      {
      chain.doFilter(request,response);
      }
      Listing 7: Implementing the doFilter method

      Above, we use the FilterChain passed into our Filter to call the next filter in the Filter Chain when the Container invokes the doFilter() method of this Filter.

      If there is no more filters available, the container will make sure that the target of the original request is called.

    4.5 Step 5: Add utility method to get FilterConfig

      To simplify extension of this class, we add a utility method that will be used to get the current FilterConfig.

      Add the following method to your source:


      public FilterConfig getFilterConfig()
      {
      return filterConfig;
      }
      Listing 8: Implementing the getFilterConfig method.

    4.6 Step 6: Add the init method

      Add the following required method to your source:


      public void init(FilterConfig config)
      {
      this.filterConfig = config;
      }
      Listing 9: Implementing the init method.

      This method will be called by the Container upon initialising the Filter. In the method, we make sure to keep the FilterConfig given to us by the Container in our instance variable.

    4.7 step 7: Add the destroy method and end the class

      Add the following to your source:


      public void destroy()
      {
      this.filterConfig = null;
      }
      }
      Listing 10: Implementing the destroy method.

      The method we added to the source above will be called by the Container when the current Filter intstance should be removed from service. This is where you perform any cleanup operations.

      Your GenericFilter.java should now look like this.

    4.8 step 8: Compile your Filter

      Your GenericFilter.class should be located in the 'orion/default-web-app/WEB-INF/classes/com/acme/filter/' directory when done.

5 Writing your first Filter

    Our very first Filter will write out messages to standard out whenever it is invoked. We want it to tell us when its entered and exited. The only thing we want the Filter to do at this time is to add the text 'Hello World' as a Request attribute by the name of 'hello'. In order to implement this Filter we will extend the GenericFilter created above.


    Figure 5: The HelloWorldFilter extends the GenericFilter and overrides the doFilter method.

    This section contains the following steps:



    5.1 Step 1: Create a file named 'HelloWorldFilter.java'

      Start up your editor and start editing a source file with the name 'HelloWorldFilter.java'

    5.2 Step 2: Add import statements

      Start of with the package name and any imports we need, so that your source looks like the following:


      package com.acme.filter;

      import javax.servlet.FilterChain;
      import javax.servlet.ServletRequest;
      import javax.servlet.ServletResponse;
      import java.io.IOException;
      import javax.servlet.Filter;
      Listing 11: The import statements

      This will make sure that we have the neccessary classes available.

    5.3 Step 3: Add class declaration

      Continue with the following:


      public class HelloWorldFilter extends GenericFilter
      {
      Listing 12: The class declaration

      Above, we make sure that our class extends the GenericFilter class we created previously.

    5.4 Step 4: override the doFilter method

      We should now override the doFilter() method in the following way:


      public void doFilter(final ServletRequest request,final ServletResponse response, FilterChain chain)
      throws IOException, ServletException
      {
      System.out.println("Entering Filter");
      request.setAttribute("hello","Hello World!");
      chain.doFilter(request,response);
      System.out.println("Exiting Filter");
      }
      }
      Listing 13: Overriding the doFilter method

      Above, we first print out some messages, and then add a message to a Request attribute with the name of 'hello'. After that, we use the FilterChain that the container has given us. We then invoke the doFilter() method on the next Filter in the Chain.

      If there is no more filters available, the container will make sure that the target of the original request is called.

      And that was it! Simple or what?

      Your HelloWorldFilter.java should now look like this.

    5.5 step 5: Compile your Filter

      Your HelloWorldFilter.class should be located in the 'orion/default-web-app/WEB-INF/classes/com/acme/filter/' directory when done.

6 Creating a JSP page to test the Filter

    Now, in order to use our filter we need to attach that filter to something. We will create a real simple JSP page and place it in the root of the default-web-app.

    We will go through the following steps to create the JSP file:



    6.1 step 1: Create a file named 'filter.jsp'

      Fire up your editor so that you can create a file called 'filter.jsp'

    6.2 step 2: Write the source

      Add the following to your file:


      <HTML>
      <HEAD>
      <TITLE>Lesson 1</TITLE>
      </HEAD>
      <BODY>
      <HR>
      <P><%=request.getAttribute("hello")%></P>
      <P>Check your console output!</P>
      <HR>
      </BODY>
      </HTML>
      Listing 14: The filter.jsp file

      The JSP page above will try to print out a Request attribute with the name "hello" to the page.

    6.3 step 3: Save the JSP page

      Save your file in the 'orion/default-web-app/' directory with the name 'filter.jsp'.

      Your filter.jsp should now look like this.

7 Configuring your Filter

    It is now time for us to configure our Filter usage.

    To do so we will go through the following steps:



    7.1 Step 1: Configure Filter existence in web.xml

      Start up your editor and open the file 'orion/default-web-app/WEB-INF/web.xml'.

      After the staring <web-app>, after any </display-name> or </description>, add the following rows:


      <filter>
      <filter-name>helloWorld</filter-name>
      <filter-class>com.acme.filter.HelloWorldFilter</filter-class>
      </filter>
      Listing 15: Configuring the Filter entry.

      This will tell the container that our web-application has a filter that we will refer to as 'helloWorld', which represents the class 'com.acme.filter.HelloWorldFilter'.

    7.2 Step 2: Configure Filter mapping in web.xml

      Directly after the code section above, add the following:


      <filter-mapping>
      <filter-name>helloWorld</filter-name>
      <url-pattern>/filter.jsp</url-pattern>
      </filter-mapping>
      Listing 16: Mapping the Filter to a URL-pattern

      This will tell our container that within this web-application, any requests for '/filter.jsp' will first invoke the filter named 'helloWorld'.

      Now is this simple or what?

    7.3 Step 3: Save changes to web.xml

      Save your 'web.xml' and make sure that it is located in the 'orion/default-web-app/WEB-INF/' directory.

      Your web.xml should now look something like this.

8 Testing your Filter

    It is now time to test your first Filter.

    We will do so in the following steps:



    8.1 Step 1: Make sure Orion is running

      Make sure that your Orion Application Server is up and running.

    8.2 Step 2: Open the URL

      Open up the location 'http://localhost/filter.jsp' in a normal browser.

      Substitute 'localhost' with the name of the server you are working with if needed.

      The result should be a page saying 'Hello World!' and telling you to view your console for any output.

    8.3 Step 3: Check the console output

      Check your console output.

      The console output should look something like:


      Entering Filter
      Exiting Filter
      Listing 17: Example output.

    Congratulations! You have just created and successfully tested your first Filter!

    Continue with Lesson 2, Your first parameterised Filter.

Copyright © 2003 IronFlare AB