Taming your Tomcat: Filtering tricks for Tomcat 5

Designing maintainable high-performance systems

The new Tomcat 5 server takes filters to a new level of deployment flexibility. Tomcat 5's support for the upcoming Servlet 2.4 and JSP 2.0 specifications gives filter writers a new way to integrate and deploy these flexible components -- tapping directly into the request dispatcher's operations. In this article, Sing Li takes you on a guided tour of the new enhancement and gives you some hands-on training. See how Tomcat 5 can benefit Web application frameworks and lead ultimately to the design of maintainable high-performance systems.

Sing Li (westmakaha@yahoo.com), Author, Wrox Press

Photo of Sing LiSing Li is the author of Early Adopter JXTA and Professional Jini, as well as numerous other books with Wrox Press. He is a regular contributor to technical magazines and is an active evangelist of the P2P evolution. Sing is a consultant and freelance writer and can be reached at westmakaha@yahoo.com.



25 March 2003

Also available in Japanese

Back in June 2001, I wrote an article that previewed the (then) brand-new Servlet 2.3 feature called filtering. The Tomcat 4.x server supported this feature, and filters enabled Web application developers to create flexible application components that could be inserted and chained into the application server's request flow -- before and after the actual request was processed. And because filters are packaged as application-level components, on a par with JSP pages and servlets, they can easily be bundled in the same WAR file for deployment on any Servlet 2.3-compliant server. Since then, major application server vendors have embraced the Servlet 2.3 standard to support filtering, and filters have become a cornerstone component of many Web applications.

Servlet 2.4 filter enhancements

Based on actual "in-the-field" feedback from the Web development community, the Servlet 2.4 specification -- now being finalized -- gives filters a single, highly important new capability. This new capability finally enables filters to play on completely level ground with servlets and JSP pages, enabling Web application designers to add major application functionality using filters. This new capability also facilitates a highly popular new style of Web application design called JSP Model 2, or Model View Controller (MVC) Web application design. (See Resources for more information on JSP Model 2 or MVC-styled Web application design.)


Filters in the request dispatcher's processing flow

The new filtering feature in Servlet 2.4 basically alleviates the restriction that filters can only operate in the request flow before and after the actual request processing by the application server. Instead, Servlet 2.4 filters can now interact with the request dispatcher at every dispatch point. This means that when a Web resource forwards a request to another resource (for instance, a servlet forwarding the request to a JSP page in the same application), a filter can be operating before the request is handled by the targeted resource. It also means that should a Web resource include the output or function from other Web resources (for instance, a JSP page including the output from multiple other JSP pages), Servlet 2.4 filters can work before and after each of the included resources. Figure 1 illustrates the difference between Servlet 2.3 and Servlet 2.4's dispatcher interactions.

Figure 1. Servlet 2.3 and Servlet 2.4 filter differences
Servlet 2.3 and Servlet 2.4 Filter Differences

Controlling filter dispatcher interactions

The interaction of filters with the container's request processing flow is configured through the <filters-mapping> element definition in the deployment descriptor (web.xml file). This is the convention established in the Servlet 2.3 specification, and it has not changed in Servlet 2.4. Instead, the new ability to interact with the dispatcher is controlled through a new optional <dispatcher> sub-element. Listing 1 shows a <filters-mapping> element in a deployment descriptor that uses the <dispatcher> sub-element to apply a filter called "Blue Filter" to any JSP page that may be included (assuming that all the JSP pages in the application are mapped to the /jsp/* URL pattern):

Listing 1. Servlet 2.4-styled filter mapping
<filter-mapping>
           <filter-name>Blue Filter</filter-name>
           <url-pattern>/jsp/*</url-pattern>
           <dispatcher>INCLUDE</dispatcher>
 </filter-mapping>

To apply the same filter to dispatcher-forwarded resources as well as included resources, we simply add another <dispatcher> sub-element, as shown in Listing 2:

Listing 2. Mapping forwards and includes
<filter-mapping>
           <filter-name>Blue Filter</filter-name>
           <url-pattern>/jsp/*</url-pattern>
           <dispatcher>INCLUDE</dispatcher>
           <dispatcher>FORWARD</dispatcher>
 </filter-mapping>

The values that a <dispatcher> sub-element can contain are shown in Table 1:

Table 1. Possible values for a <dispatcher> sub-element
ValueDescription
REQUESTApply filter to request originating from the client -- exactly the same as the default behavior in Servlet 2.3-compliant containers.
FORWARDApply filter to request as it is being forwarded using the Dispatcher.forward() call between Web resources.
INCLUDEApply filter to request as Web resources are being included through Dispatcher.include() calls.
ERRORApply filter to an error processing resource (essentially a container-managed forward mechanism when an error occurs).

All of the values in Table 1, of course, are still subjected to the match specified by the <url-pattern> sub-element of <filter-mapping>. Essentially, only the URLs that match the <url-pattern>and the <dispatcher> sub-element will be filtered.

To better appreciate the operation of the new filter/dispatcher interactions, let's put some filters to work in a Tomcat server.

Downloading and installing Tomcat 5 plus JSTL

All code has been fully tested under Tomcat 5.0 alpha, the latest release build available at the time this article was written. In addition to installing Tomcat, you need to download the JSTL 1.0 binaries. Place standard.jar and jstl.jar into the webapps/dvworks/web-inf/lib directory, and all the TLD files under the webapps/dvworks/web-inf directory. (See Resources) for more information on installing Tomcat and downloading the JSTL 1.0 binaries.)


Configuring Tomcat 5 filters

Assuming you have Tomcat 5 installed and running with the JSP Standard Tag Library 1.0 (see the sidebar "Downloading and installing Tomcat 5 plus JSTL"), we can now work with some actual filter examples. Download the source code to get our sample Web application.

Let's look at the coding of a couple of JSP pages and filters. The resources we'll work with initially are:

  • /jsp/filtercount.jsp
  • /jsp/included.jsp
  • AddAttributesFilter
  • RedFilter

The filtercount.jsp resource is quite simple, and consists of the code shown in Listing 3:

Listing 3. Code for filtercount.jsp
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<HTML>
<HEAD>
</HEAD>
<BODY>
<H1>developerWorks Tomcat 5 Filters</H1>

<jsp:include page="/jsp/included.jsp">
  <jsp:param name="BoxColor" value="red"/>
</jsp:include>

<br/>
<FONT FACE="verdana,arial,sans serif" SIZE="4">
<c:if test="${(requestScope.BlueCounter != null) && 
    (requestScope.BlueCounter > 0)}">
  <font color="blue">The BlueFilter has been activated 
      ${requestScope.BlueCounter} times.</font></br>
</c:if>
<c:if test="${(requestScope.RedCounter != null) && 
    (requestScope.RedCounter > 0)}">
  <font color="red">The RedFilter has been activated 
      ${requestScope.RedCounter} times.</font></br>
</c:if>
</FONT>
</BODY>
</HTML>

This JSP page calls the dispatcher to include another JSP page called /jsp/included.jsp. It also uses the JSTL Expression Language to print out the value of two counters (RedCounter and BlueCounter) that are attached as attributes to the incoming request, if the counter exists, and if the count is greater than zero.

In fact, each counter is used to count the number of times that either RedCounter or BlueCounter is called during request processing. Table 2 shows the filters we will use and what they actually do.

Table 2. Names and functions of filters in experiment scenarios
Filter NameDescription
AddAttributesFilterAdd the BlueCounter and RedCounter attributes to the incoming request.
RedFilterIncrement the value of the RedCounter attribute attached to the request.
BlueFilterIncrement the value of the BlueCounter attribute attached to the request.

All of the filters in Table 2 are part of the com.ibm.dvworks.filters package.

The code for com.ibm.dvworks.filters.AddAttributesFilter is presented in Listing 4. Note that it simply creates the two counter attributes as java.lang.Integer type, which has a value of 0.

Listing 4. Code for AddAttributesFilter.java
package com.ibm.devworks.filters;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;


public final class AddAttributesFilter implements Filter {

    public static final String RED_COUNTER_ATTRIB = "RedCounter";
    public static final String BLUE_COUNTER_ATTRIB = "BlueCounter";


    private FilterConfig filterConfig = null;

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

        request.setAttribute(RED_COUNTER_ATTRIB, new Integer(0));
        request.setAttribute(BLUE_COUNTER_ATTRIB, new Integer(0));
        filterConfig.getServletContext().log("Inside AddAttributesFilter");
        chain.doFilter(request, response);

    }


    public void destroy() {
        this.filterConfig = null;
    }


    public void init(FilterConfig filterConfig) {
	this.filterConfig = filterConfig;

    }

}

The construction of this filter follows the basic filter coding pattern. Again, refer to the first article for more details on coding filters.

Similarly, com.ibm.dvworks.filters.RedFilter has the code shown in Listing 5. Note that the code simply looks for the RedCounter attribute and increments it if found.

Listing 5. Code for RedFilter.java
package com.ibm.devworks.filters;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;


public final class RedFilter implements Filter {

    public static final String COUNTER_ATTRIB = "RedCounter";
    private FilterConfig filterConfig = null;

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

    filterConfig.getServletContext().log("Inside RedFilter");
    Integer curCount = (Integer) request.getAttribute(COUNTER_ATTRIB);
    if (curCount != null)
        request.setAttribute(COUNTER_ATTRIB, 
            new Integer(curCount.intValue() + 1));

      chain.doFilter(request, response);

    }


    public void destroy() {
        this.filterConfig = null;
    }


    public void init(FilterConfig filterConfig) {
	this.filterConfig = filterConfig;

    }

}

The com.ibm.dvworks.filters.BlueFilter class has identical code to RedFilter, except the constant COUNTER_ATTRIB is defined to be BlueFilter, as shown in Listing 6:

Listing 6. Code change for BlueFilter
public static final String COUNTER_ATTRIB = "BlueCounter";

The filtercount.jsp file uses the dispatcher to include the included.jsp file. The included.jsp file simply creates a table that is filled with the color specified by the input parameter called BoxColor. Note the use of the Expression Language (EL) in rendering the color in the table, as shown in Listing 7:

Listing 7. Code for included.jsp
<table border="1" bgcolor="${param.BoxColor}" cellpadding="5">
      <tr> 
      <td>this page is included in-line using dispatcher</td>
      </tr>
</table>

With these filters and JSP pages, we are ready to begin our exploration of five different filter configuration scenarios.

Scenario 1: Standard Servlet 2.3 filter interaction -- REQUEST only

In this first scenario, we will configure our filters to work in a manner supported by older Servlet 2.3 containers.

The <filter-mapping> element that we will use is shown in Listing 8:

Listing 8. Filter mapping for Standard Servlet 2.3 compatibility
<filter-mapping>
  <filter-name>Add Attributes Filter</filter-name>
  <url-pattern>/jsp/*</url-pattern>
</filter-mapping>
<filter-mapping>
  <filter-name>Red Filter</filter-name>
  <url-pattern>/jsp/*</url-pattern>
</filter-mapping>

Edit your web.xml to reflect the Listing 8 configuration. Here, we are not specifying a <dispatcher> sub-element. This means that the filters will be applied on a REQUEST-only basis, as it did in Servlet 2.3 containers. The configuration in Listing 8 is operationally identical to the code in Listing 9:

Listing 9. Equivalent Servlet 2.4 filter mapping
<filter-mapping>
  <filter-name>Add Attributes Filter</filter-name>
  <url-pattern>/jsp/*</url-pattern>
  <dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter-mapping>
  <filter-name>Red Filter</filter-name>
  <url-pattern>/jsp/*</url-pattern>
  <dispatcher>REQUEST</dispatcher>
</filter-mapping>

Start Tomcat 5, and access the Web application using the http://<hostname>:8080/dvworks/jsp/filtercount.jsp URL. Figure 2 shows the response generated by filtercount.jsp:

Figure 2. Servlet 2.3-compatible REQUEST filtering
Servlet 2.3 Compatible REQUEST Filtering

According to the filtercount.jsp response, RedFilter has been called only once in this scenario. Figure 3 is a detailed interaction diagram showing the request flow through the request processors:

Figure 3. Servlet 2.3 filtering request flow
Servlet 2.3 Filtering Request Flow

In Figure 3, the filter chain is called only once -- as the request enters the system from the client. The filter chain, of course, consists of AddAttributesFilter and RedFilter, as shown in Figure 4:

Figure 4. Details of the filter chain
Details of the filter chain

In this Servlet 2.3-styled configuration, RedFilter is applied only once on the incoming request directly from the client.

Scenario 2: Combining REQUEST and INCLUDE interactions

The filter mapping we will use for this scenario is shown in Listing 10. Note the use of the Servlet 2.4 syntax and the addition of the INCLUDE dispatcher sub-element to RedFilter.

Listing 10. Filter mapping for combined REQUEST and INCLUDE interactions
<filter-mapping>
  <filter-name>Add Attributes Filter</filter-name>
  <url-pattern>/jsp/*</url-pattern>
  <dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter-mapping>
  <filter-name>Red Filter</filter-name>
  <url-pattern>/jsp/*</url-pattern>
  <dispatcher>REQUEST</dispatcher>
  <dispatcher>INCLUDE</dispatcher>
</filter-mapping>

Restart Tomcat 5 and access the application again with the http://<hostname>:8080/dvworks/jsp/filtercount.jsp URL. The response shown in Figure 5 displays the filter count.

Figure 5. REQUEST and INCLUDE filtering
REQUEST and INCLUDE Filtering

Now RedFilter has been called twice -- once during the incoming request, and the second time with the inclusion of included.jsp. The two calls are detailed in the interaction diagram shown in Figure 6. Note that we have simplified the diagram by showing only the flow of the request into the system (and not the detailed return flow as was done previously).

Figure 6. Combined REQUEST and INCLUDE interaction
Combined REQUEST and INCLUDE Interaction

Scenario 3: Combining REQUEST, INCLUDE, and FORWARD interactions

Next, we will bring in another simple JSP page, called forwarder.jsp, shown in Listing 11. It simply uses the dispatcher to forward the incoming request to filtercount.jsp.

Listing 11. Code for forwarder.jsp
<jsp:forward page="/jsp/filtercount.jsp"/>

Now we can add BlueFilter to the deployment descriptor, as shown in Listing 12:

Listing 12. Filter mapping for combined REQUEST, INCLUDE, and FORWARD interactions
<filter-mapping>
  <filter-name>Add Attributes Filter</filter-name>
  <url-pattern>/jsp/*</url-pattern>
  <dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter-mapping>
  <filter-name>Red Filter</filter-name>
  <url-pattern>/jsp/*</url-pattern>
  <dispatcher>REQUEST</dispatcher>
  <dispatcher>INCLUDE</dispatcher>
</filter-mapping>
<filter-mapping>
  <filter-name>Blue Filter</filter-name>
  <url-pattern>/jsp/*</url-pattern>
  <dispatcher>FORWARD</dispatcher>
</filter-mapping>

BlueFilter is configured to handle forwarded requests only, while the rest of the filter mapping remains unchanged.

Restart Tomcat 5 and access the application with the http://<hostname>:8080/dvworks/jsp/forwarder.jsp URL. Figure 7 shows the response.

Figure 7. REQUEST, INCLUDE, and FORWARD filtering
REQUEST, INCLUDE, and FORWARD Filtering

In this case, we see that BlueFilter is actually called once -- during the forwarding of the request from forwarder.jsp to filtercount.jsp. The interaction diagram in Figure 8 shows the flow.

Figure 8. Combined REQUEST, INCLUDE, and FORWARD interactions
Combined REQUEST, INCLUDE, and FORWARD Interactions

Scenario 4: Combining REQUEST, INCLUDE, FORWARD, and legacy Servlet 2.3 interactions

In this scenario, we are adding a filter from the previous filtering article. You can use ReplaceTextFilter to replace text in the response. We configure it using initial parameters in the <filter> definition shown in Listing 13:

Listing 13. Filter definition for ReplaceTextFilter with initialization parameters
    <filter>
        <filter-name>Replace Text Filter</filter-name>
        <filter-class>com.ibm.devworks.filters.ReplaceTextFilter
        </filter-class>
         <init-param>
	    <param-name>search</param-name>
	    <param-value>color="red"</param-value>
	  </init-param>
        <init-param>
	    <param-name>replace</param-name>
	    <param-value>color="green"</param-value>
	  </init-param>
    </filter>

We then add the following <filter-mapping> to the ones used in the previous scenario, as shown in Listing 14:

Listing 14. Filter mapping for combined REQUEST, INCLUDE, FORWARD, and legacy Servlet 2.3 filter interactions
<filter-mapping>
  <filter-name>Replace Text Filter</filter-name>
  <url-pattern>/jsp/*</url-pattern>
</filter-mapping>
...

Note that we are not specifying a <dispatcher> sub-element here, and therefore this filter is defaulting to REQUEST-only processing.

Restart Tomcat 5 and access the http://<hostname>:8080/dvworks/jsp/forwarder.jsp URL. You should see something similar to Figure 9. Unlike the previous configuration, now the included box is green.

Figure 9. Combined REQUEST, INCLUDE, FORWARD, and legacy filtering
Combined REQUEST, INCLUDE, FORWARD and Legacy Filtering

The interaction diagram shown in Figure 10 illustrates how ReplaceTextFilter is handed the response for final processing before passing it back to the client. It is here that the color of the table is changed from red to green.

Figure 10. Combined REQUEST, INCLUDE, FORWARD, and legacy interactions
Combined REQUEST, INCLUDE, FORWARD and Legacy Interactions

Servlet 2.4 containers are completely backward compatible with Servlet 2.3 filters, definitions, and mappings.

Scenario 5: Filtering on ERROR dispatch

For the final scenario, we will briefly examine the application of a filter when dispatching to an error-handling page. The filter mapping that we will use is in Listing 15. Make sure you remove all other filter mappings in web.xml.

Listing 15. Filtering on ERROR
<filter-mapping>
  <filter-name>Red Filter</filter-name>
  <url-pattern>/jsp/*</url-pattern>
  <dispatcher>REQUEST</dispatcher>
  <dispatcher>INCLUDE</dispatcher>
  <dispatcher>ERROR</dispatcher>
</filter-mapping>

To purposely generate an error, we create a JSP page, called errorgen.jsp, which sets up a page called errorhdlr.jsp to handle an error, and then throws an exception, as shown in Listing 16:

Listing 16. Code for errorgen.jsp
<%@page errorPage="/jsp/errorhdlr.jsp" %>

<% 
    if (true)
      throw (new Exception("Purposely generated exception!")); 
%>

When an error is caught by the page, the container forwards the request to the /jsp/errorhdlr.jsp page, as specified in the @page directive. The errorhdlr.jsp page contains the code shown in Listing 17:

Listing 17. Code for errorhdlr.jsp
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<%@page isErrorPage="true" %>
<HTML>
<HEAD>
</HEAD>
<BODY>
<H1>developerWorks Tomcat 5 Error Page</H1>

<br/>
<FONT FACE="verdana,arial,sans serif" SIZE="4">
<c:if test="${(requestScope.BlueCounter != null) && 
    (requestScope.BlueCounter > 0)}">
  <font color="blue">The BlueFilter has been activated 
      ${requestScope.BlueCounter} times.</font><br/>
</c:if>
<c:if test="${(requestScope.RedCounter != null) && 
    (requestScope.RedCounter > 0)}">
  <font color="red">The RedFilter has been activated 
      ${requestScope.RedCounter} times.</font><br/>
</c:if>
<br/>
Error information:<br/>
<i>${pageContext.errorData.throwable.message}</i>
</FONT>
</BODY>

The errorhdlr.jsp prints out the filter counter values, then prints out the message of the exception being caught using the EL.

Restart Tomcat 5 and access the http://<hostname>:8080/dvworks/jsp/errorgen.jsp URL. Even though you attempt to access errorgen.jsp, it is errorhdlr.jsp that will be displayed (because an exception is explicitly thrown). The error page that you will see is shown in Figure 11:

Figure 11. REQUEST and ERROR filtering
REQUEST and ERROR Filtering

Note that RedFilter has been called twice -- once at the REQUEST level and a second time when the container forwards to the error page.

You can apply Servlet 2.4 filters just before the processing of a custom error-handling Web resource.


Filters and Model 2 Web application frameworks

The enhanced filtering capability in Tomcat 5 provides new deployment opportunities when using popular application frameworks. Frameworks such as Struts and Turbine (see Resources) use a JSP Model 2 architecture to separate data operations (the Model in an MVC pattern) from the business logic operations, and the presentation operations (the View). Their functionality centers around the use of a switching servlet (the Controller servlet) that forwards incoming requests to different user-created Action components, either according to a static XML directive file or using runtime introspection. These requests are typically further forwarded between components, until the response is complete. The Model 2 architecture enables designers to componentize their server-side coding for adaptability to change and easier long-term maintenance.

Because the dispatcher is used extensively to forward requests between the controller servlet and the application components, as well as between application components, you can readily add filters to the processing flow. With the Servlet 2.4 enhancements, filters can now become an integral part of a Web application's components mix -- when using Model 2 application frameworks.

An architectural pattern from the hardware domain

A novel way of thinking of a cluster of servers running a maximally scaled Web application is through the analogy of a microprocessor. Incoming requests span a finite set of possible operations like a CPU's instruction set. Processing of requests by the servers is analogous to the execution of instructions by the hardware core.


Pipelining your application toward a high-performance future

Pipelining is a request flow-centric view of componentized request processing. It focuses on the multistage processing of a single request as it flows through the application server.

In the pipeline model, a request flows through an assembly line (the pipeline) while at each stage being modified/transformed/processed by a series of processors, until finally the response is generated and expedited back to the client. Popular Web application frameworks such as Jakarta Struts and Turbine, through the virtue of their JSP Model 2 architecture, already componentize the server-side logic in a pipelined fashion.

Figure 12 shows the typical pipeline stages that a Web application or service request may flow through when displaying a page of data:

Figure 12. Typical stages of the pipeline model
Typical Stages of the Pipeline Model

In summary, the request is passed through the three pipeline stages shown in Table 3:

Table 3. Pipeline model stages
Name of pipeline stageDescription of typical operation performed
Data fetchFetches data from external systems (such as JDBC datasource), based on information from the incoming request
ProcessingValidates or transforms data elements using the value of the data element to look up further data, such as from internal or external sources
RenderingCreates the output response based on the processed data, typically in a visual format (such as HTML) or an interchange format (such as XML)

By placing design focus on the request processing pipeline, Web application design is entering a new era of performance tuning and optimization possibilities. Many of the same techniques being exploited in modern microprocessor hardware design -- in the optimization of pipelines -- can be leveraged in the near future for optimization of Web application server software and hardware.

For example, in a Web application that has similar requirements for every request flowing through the data fetch stage of processing, the optimized application server/hardware platform can prefetch and locally cache the most commonly accessed data -- completely eliminating the data fetch overhead for most incoming requests. Another example -- for requests that demand significant CPU processing resources in the rendering stage, such as XSLT transformation or other XML parsing -- a parallel bank of hardware-accelerated XML processors can be configured in the rendering stage of the pipeline. While these optimizations are still slightly futuristic in terms of practical ability to implement them today, designing Web applications with consideration for the pipeline model is a necessary element to make them reality.


Conclusions

Tomcat 5's new filtering feature enables us to tap into every stage of the Web application's request-processing flow. This capability facilitates the use of filters with application frameworks and opens up new performance optimization and tuning possibilities.


Download

DescriptionNameSize
Code samplej-tomcat2.zip7KB

Resources

  • Download the Web application, filters, and JSP source code for this article.
  • Download the latest version of Apache Tomcat at the official Tomcat Web site. You can download the Tomcat 5.0 server.
  • Download the latest version of JSTL at the Apache Jakarta Taglib site. You can obtain the specification at JSR-52.
  • At the time of publication, Mark Kolb is in the process of writing a four-part series on JSTL. Part 1, "The expression language" (developerWorks, February 2003), introduces JSTL and the EL; Part 2, "Getting down to the core" (developerWorks, March 2003), details flow control and URL management through custom tags.
  • Filtering enhancements are described in the Servlet 2.4 specification. You can find the latest in JSR-154.
  • The latest status and more information on the JavaServer Pages 2.0 specification, including coverage of the proposed Expression Language (EL), can be found in JSR-152.
  • Learn more about Model 2 Web application development using the Struts application framework. See the official Struts Web site for detailed information and the latest developments.
  • You'll find hundreds of articles about every aspect of Java programming in the developerWorks Java technology zone.

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Java technology on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Java technology
ArticleID=10790
ArticleTitle=Taming your Tomcat: Filtering tricks for Tomcat 5
publish-date=03252003