The Java Servlet specification version 2.3 introduces a new component type, called a filter. A
filter
dynamically intercepts requests and responses to transform or use the
information contained in the requests or responses. Filters typically do
not themselves create responses, but instead provide universal
functions that can be "attached" to any type of servlet or JSP page.
Filters are important for a
number of reasons. First, they provide the ability to encapsulate
recurring tasks in reusable units. Organized developers are constantly
on the lookout for ways to modularize their code. Modular code is more
manageable and documentable, is easier to debug, and if done well, can
be reused in another setting.
Second, filters can be
used to transform the response from a servlet or a JSP page. A common
task for the web application is to format data sent back to the client.
Increasingly the clients require formats (for example, WML) other than
just HTML. To accommodate these clients, there is usually a strong
component of transformation or
filtering in a
fully featured web application. Many servlet and JSP containers have
introduced proprietary filter mechanisms, resulting in a gain for the
developer that deploys on that container, but reducing the reusability
of such code. With the introduction of filters as part of the Java
Servlet specification, developers now have the opportunity to write
reusable transformation components that are portable across containers.
Filters can perform many different types of functions. We'll discuss examples of the italicized items in this paper:
-
- Authentication-Blocking requests based on user identity.
- Logging and auditing-Tracking users of a web application.
- Image conversion-Scaling maps, and so on.
- Data compression-Making downloads smaller.
- Localization-Targeting the request and response to a particular locale.
- XSL/T transformations of XML content-Targeting web application responses to more that one type of client.
These are just a few of
the applications of filters. There are many more, such as encryption,
tokenizing, triggering resource access events, mime-type chaining, and
caching.
In this paper we'll first discuss how to program filters to perform the following types of tasks:
-
- Querying the request and acting accordingly
- Blocking the request and response pair from passing any further.
- Modifying the request headers and data. You do this by providing a customized version of the request.
- Modifying the response headers and data. You do this by providing a customized version of the response.
We'll outline the filter API, and describe how to develop customized requests and responses.
Programming the filter is
only half the job of using filters-you also need to configure how they
are mapped to servlets when the application is deployed in a web
container. This decoupling of programming and configuration is a prime
benefit of the filter mechanism:
-
- You don't have to recompile
anything to change the input or output of your web application. You just
edit a text file or use a tool to change the configuration. For
example, adding compression to a PDF download is just a matter of
mapping a compression filter to the download servlet.
- You can experiment with filters easily because they are so easy to configure.
The last section of this
paper shows how to use the very flexible filter configuration mechanism.
Once you have read this paper, you will be armed with the knowledge to
implement your own filters and have a handy bag of tricks based on some
common filter types.
Programming Filters
The filter API is defined by the
Filter
,
FilterChain
, and
FilterConfig
interfaces in the
javax.servlet
package. You define a filter by implementing the
Filter
interface. A filter chain, passed to a filter by the container,
provides a mechanism for invoking a series of filters. A filter config
contains initialization data.
The most important method in the
Filter
interface is the
doFilter
method, which is the heart of the filter. This method usually performs some of the following actions:
-
- Examines the request headers
- Customizes the request object if it wishes to modify request headers or data or block the request entirely
- Customizes the response object if it wishes to modify response headers or data
- Invokes the next entity in the
filter chain. If the current filter is the last filter in the chain that
ends with the target servlet, the next entity is the resource at the
end of the chain; otherwise, it is the next filter that was configured
in the WAR. It invokes the next entity by calling the
doFilter
method on the chain object (passing in the request and response it was
called with, or the wrapped versions it may have created).
Alternatively, it can choose to block the request by not making the call
to invoke the next entity. In the latter case, the filter is
responsible for filling out the response.
- Examines response headers after it has invoked the next filter in the chain
- Throws an exception to indicate an error in processing
In addition to
doFilter
, you must implement the
init
and
destroy
methods. The in
it
method is called by the container when the filter is instantiated. If
you wish to pass initialization parameters to the filter you retrieve
them from the
FilterConfig
object passed to
init
.
Reference Link for Detail and Examples