advertisement
javaboutique
Search Tips
Articles  |   Tutorials  |   Reviews  |   Tools  |   by Category  |   by Date  |   by Name  |   Submit  |   Source  |   Forums  |  
javaboutique
Browse DevX


Partners & Affiliates











advertisement

The <filter-mapping> block

Now we need to tell the servlet container when to apply the filter, which is done with a <filter-mapping> block. The filter-mapping block includes the filter-name, which must match the name given in a <filter> block, and either a URL pattern or a servlet name. Most often you will use a URL pattern, but you can also specify the name of a servlet as defined in a <servlet> block.

URL patterns for filter-mappings are the same as for the <servlet-mapping> block, normally either a subpath such as "/secure/*", or a file ending like "*.gif". Exact paths may also be used, like "/filtered_page.html".

To have our filter handle all requests, we'll use the following filter-mapping block:

    <filter-mapping>
        <filter-name>Timer</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>    

This filter will run for every single request handled by the servlet engine. In most cases this would put an unnecessary load on the server, since few filters really need to execute for every image file as well as flat HTML, JSP, and servlet calls.

Using the FilterConfig object

When the servlet container starts it initializes each filter by calling the init() method, passing in a FilterConfig object. This object has two main uses, obtaining initialization parameters and accessing the container's ServletContext.

Initialization parameters are set in the web.xml file, in the <filter> block, and are accessed by calling FilterConfig.getInitParameter(). The names of all parameters can be retrieved with getInitParameterNames().

The ServletContext is useful for accessing data and services relating to the servlet container and the web application. For instance, it is generally better to send output to the container's log file rather than printing to standard output, as the TimerFilter code earlier in this article does. The original ExampleFilter code from the Tomcat project does this by saving a reference to FilterConfig in a class variable, and then gets the servlet context to call its log() method.

Let's look at the original Tomcat ExampleFilter code to see this in action. Not only does it use ServletContext, it also uses a configuration parameter to create a request attribute that could be retrieved by a servlet, JSP, or another filter. Although not obviously useful here, this is a handy technique for passing data between the components of a web application.

In its init() method the filter saves the FilterConfig object in an object variable, along with the "attribute" initialization parameter.

    private FilterConfig filterConfig = null;
    private String attribute = null;

    public void init(FilterConfig filterConfig) throws ServletException {

        this.filterConfig = filterConfig;
        this.attribute = filterConfig.getInitParameter("attribute");

    }

Then the doFilter() method uses the FilterConfig to grab the ServletContext and use its log() method to write to the log file. It also sets an attribute in the request named according to the init-parameter, whose value is the ExampleFilter object itself. This could be used in a JSP page or servlet, or a later Filter.

    
    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain)
        throws IOException, ServletException {

        // Store ourselves as a request attribute (if requested)
        if (attribute != null)
            request.setAttribute(attribute, this);

        // Time and log the subsequent processing
        long startTime = System.currentTimeMillis();
        chain.doFilter(request, response);
        long stopTime = System.currentTimeMillis();
        filterConfig.getServletContext().log
            (this.toString() + ": " + (stopTime - startTime) +
             " milliseconds");

    }

Overriding the request or response

In most cases filters need to affect what happens later in the request process, even if later components or the resource being accessed don't know anything about the filter. A powerful way to do this is to substitute your own request or response object when calling the FilterChain.doFilter() method. The servlet specification offers special wrapper classes for this purpose, which can be subclassed to override their default behavior. The replacement class is instantiated passing in the original request or response object, so methods which aren't overridden can still be used.

This technique is particularly useful for filters that need to process the raw output of the request, for example encrypting, converting, or compressing the response data. Once again the Tomcat folks offer a good example of how to do this with CompressionFilter. Since most web browsers can automatically handle compressed pages, CompressionFilter compresses large pages on the fly. This can be applied not only to static HTML pages, but also HTML (or other format) output generated by servlets or JSP pages.

If CompressionFilter determines that the browser supports compression, it wraps the response with a CompressionServletResponseWrapper, which is a subclass of HttpServletResponseWrapper. Whatever final resource is accessed by the request will be sent to the browser by calling ServletResponse.getOutputStream() or ServletResponse.getWriter() to obtain a writer or stream to feed the output into. So the response wrapper overrides these methods, replacing the stream with a custom CompressionResponseStream that uses java.util.zip.GZIPOutputStream to compress whatever is written to it, or returning a writer which employs that same stream.

Here is the portion of CompressionFilter.doFilter() which actually wraps the response.

    if (response instanceof HttpServletResponse) {
        CompressionServletResponseWrapper wrappedResponse =
            new CompressionServletResponseWrapper((HttpServletResponse)response);
        wrappedResponse.setCompressionThreshold(compressionThreshold);
        if (debug > 0) {
            System.out.println("doFilter gets called with compression");
        }
        try {
            chain.doFilter(request, wrappedResponse);
        } finally {
            wrappedResponse.finishResponse();
        }
        return;
    }

The implementation of the custom output stream is actually more sophisticated than this. It waits to ensure the returned content is large enough to be worth compressing, and then uses the compression stream or a normal stream accordingly.

How to Add Java Applets to Your Site

New on the Java Boutique:

New Review:

Time Management Made Easy with the Quartz Enterprise Job Scheduler
Why not just use the Java timer API? This open source scheduling API boasts simplicity, ease-of-integration, a well-rounded feature set, and it's free!

New Applet:

Reverse Complement
Reverse Complement is a simple applet that converts DNA or RNA sequences into three useful formats.

Elsewhere on internet.com:

WebDeveloper Java
Lots of Java information on webdeveloper.com

WDVL Java
Thorough Java resource at the Web Developer's Virtual Library.

ScriptSearch Java
Hundreds of free Java code files to download.

jGuru: Your View of the Java Universe
Customizable portal with online training, FAQs, regular news updates, and tutorials.

 Avaya Developer Showcase
 MSDN Spotlight
 PHP for Windows Showcase
XML error: undefined entity at line 34
advertisement
Receive Articles via our XML/RSS feed
Receive Articles via our XML/RSS feed

JavaBytes
Internet Cyclone
This powerful, easy-to-use, internet optimizer is for Windows 95, 98, ME, NT, 2000 and XP. It's designed to automatically optimize your Windows settings, boosting your Internet connection up to 200%.

IBM Brings Developers Into the Cloud
Apache at 10: You Can't Buy Us
Microsoft's CodePlex Foundation Moving Forward
Apple Claims 100,000 Apps, Google Analyzes Them
Nokia Latest to Play Opera Mobile 10 Browser
PayPal Opens Up Payment Platform to Devs
Ubuntu Linux 9.10 'Karmic Koala' Starts Its Climb
IBM Links Rational Developer Tools, Tivoli Apps
Libraries Give Vista Apps a Windows 7 Look
Ubuntu: The 'Default Alternative' to Windows?

Delivering Web-based Embedded Fonts in CSS 3
Adobe Helps PHP Developers Create Rich Internet Applications
Java Developers Finding a Home at Adobe Flex
Virtualization Delivers a Dynamic Infrastructure
Consuming XML Web Services in iPhone Applications
Build a More Agile Business with IBM
POJO-Based Solutions for LDAP Access: One Good, One Better
IBM Offers Enhanced Measurement and Management for Energy Usage
IBM Helps Transformation to an Information-Based Enterprise
Top Five Touch UI-Related Design Guidelines

Advertising Info  |   Member Services  |   Contact Us  |   Help  |   Feedback  |   Site Map  |   Network Map  |   About

internet.commediabistro.comJusttechjobs.comGraphics.com

Search:

WebMediaBrands Corporate Info

Legal Notices, Licensing, Reprints, Permissions, Privacy Policy.
Advertise | Newsletters | Shopping | E-mail Offers | Freelance Jobs