Most applications have some requirements, such as security and logging, that are applicable across all application requests. To add such functionality separately to each application service would be time-consuming, error-prone, and difficult to maintain. Even implementing these services within a front controller would still require code changes to add and remove services. The sequence diagram in Figure 1 below shows how each Web resource is responsible for calling such services individually.
|
| Figure 1. Before Intercepting Filter |
The Intercepting Filter pattern wraps existing application resources with a filter that intercepts the reception of a request and the transmission of a response. An intercepting filter can pre-process or redirect application requests, and can post-process or replace the content of application responses. Intercepting filters can also be stacked one on top of the other to add a chain of separate, declaratively-deployable services to existing Web resources with no changes to source code. Figure 2 below shows a chain of two intercepting filters intercepting requests to two Web resources that they wrap.
|
| Figure 2. After Intercepting Filter |
Core J2EETM
Patterns
The Servlet
Filter
interface in the JavaTM 2 Platform, Enterprise Edition (J2EE) platform is a direct
implementation of the
Intercepting Filter pattern. The sample application defines two
servlet filters: one that mediates customer signon, and another that
enforces response encoding.
Sample application class
SignOnFilter
is an intercepting filter that intercepts all requests to the
pet store front controller. The
SignOnFilter
servlet filter detects requests for pages that require user
signon, and redirects such requests to the user signon page if
no user is currently signed on. An exhaustive explanation of
this process appears in
User
Signon and Customer Registration Module
(part of the
online document
Sample Application Design and
Implementation [
BT-SADI02
]).
Sample application class
EncodingFilter
is an intercepting filter that modifies
responses from
the pet store front controller, ensuring that the encoding of
the response is always set consistently.
EncodingFilter
shows how the servlet filter sets the response encoding of
each response, and then passes the request to the next
filter down the chain. The filter chain mechanism makes
such filters composable, so multiple intercepting filters
can wrap a single resource.
public void doFilter(ServletRequest srequest,
ServletResponse sresponse,
FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)srequest;
request.setCharacterEncoding(targetEncoding);
// move on to the next
chain.doFilter(srequest,sresponse);
}
web.xml shows how the
encoding filter is configured to wrap all requests
matching the pattern "
/*" (relative to the application
context root).
<!-- Encoding Filter Mapping Start-->
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>