http://www.developer.com/

Back to article

Compressing Server Responses in Java Enterprise Applications


August 5, 2009

In modern enterprise Java development, there are many ways to develop client/server communication. On the lower level, most communication over the wire occurs via HTTP. On the higher level, however, numerous technologies and APIs enable developers to facilitate client/server communication, including servlets, AJAX calls, RPC, numerous web services toolkits and APIs (e.g., Axis, WebLogic, Apache CXF, Xfire), and many others.

If you are using any of these technologies, chances are some or all of your client/server interaction also employs XML. XML is very useful in defining the structure of data being transferred over the wire (especially when communication is between two software systems, not humans). All web services use XML wrapped in SOAP envelopes (also represented in XML). AJAX and servlets can also talk XML, although they are not required to.

A lot of modern frameworks and toolkits also heavily rely on XML for configuration or "wiring" their internal working components together, such as the Java Spring framework, ORM tools like Hibernate or iBATIS, and many others. Even standard Java EE (JEE) containers rely on XML to resolve and load deployment descriptor files.

If your enterprise project uses XML for B2B or P2B communications, it is most likely also validates server requests and responses per a specific definition or schema. The XSD schema tells the server what the XML request and response may look like, which elements they must contain, and which elements are optional. With modern tools, you often can easily auto-generate both schema and XML from the Java object model (and vice versa) and have responses and requests validated automatically.

This article discusses the implementation of compression for server responses in Java enterprise applications, covering the benefits and drawbacks and detailing the technology design choices that may benefit from compression. It shows two different implementations of compression and explains how to test the end result with soapUI. The discussion focuses only on JEE-based application servers and assumes a familiarity with JEE project structure and technology in general.

Benefits and Drawbacks

So why would you need to compress anything in the context of client/server communication? Suppose a project is using XML heavily for communication, remembering that XSD schema was developed to be as descriptive as possible, with long element names and very complex structure.

Here is example of the project's XML schema, which references other schema files and is based on the OAGIS standard:

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema XMLns:xsd="http://www.w3.org/2001/XMLSchema" 
XMLns:sp="http://integration.standardandpoors.com/ServiceSchema/v3"
targetNamespace="http://some.com/ServiceSchema/v3" elementFormDefault="qualified"
attributeFormDefault="unqualified"> <xsd:include schemaLocation="BOD.xsd"/> <xsd:include schemaLocation="../Components/PersonSchemaType.xsd"/> <xsd:complexType name="PersonBODSchemaType"> <xsd:complexContent> <xsd:extension base="sp:BusinessObjectDocumentSchemaType"> <xsd:sequence> <xsd:element name="DataArea" type="sp:PersonDataAreaType"/> </xsd:sequence> </xsd:extension> </xsd:complexContent> </xsd:complexType> <xsd:complexType name="PersonDataAreaType"> <xsd:sequence> <xsd:element ref="sp:Name"/> <xsd:element ref="sp:Phone" minOccurs="0" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType> <xsd:element name="PersonBOD" type="sp:PersonBODSchemaType"/> </xsd:schema>

On top of that, the project employs web services, which add even more XML in the form of SOAP. The project is global and its data—wrapped in XML and in SOAP—travels around the world. The large XML payload creates performance issues and traffic bottlenecks for the application and clients. The data needs to be compressed to avoid network delays.

This is just one possible scenario, but in general any server response that is composed of large text or binary output can be compressed for performance and transferred over the wire. For small responses, compression will not be beneficial because it involves processing cycles (for decompression) on both the server and the client; it actually may decrease performance. If the communication is not over long distances, you also should use compression with care, because its benefits may be negligible or equal to the drawback of decompression time.

Compression Implementation

This article covers two similar methods to achieve compression in JEE applications:
  • A WebLogic compression filter
  • A PlanetJ compression filter

Both methods are indifferent to the contents of the response they are compressing and act on the response as a whole. In other words, these methods act as filters and can be used to compress XML responses, string responses, and even binary responses (see Figure 1).


Figure 1. Clients Initiating Requests: The clients initiating requests need to understand that the message is compressed, and then properly decompress it.

Both methods are configured in a similar way; both use the gzip algorithm to compress data. Note that because the compression algorithm is done entirely in Java it could be slower then a native implementation. (See the code download for the actual JAR files.)

WebLogic Compression Filter

To set up this compression filter in your web application, import the JAR library file into the project, add filter mapping in the web.xml, and then map all resources that can benefit from compression, such as .txt, .log, .html, or /wsdl/* for web services. Take these simple steps as follows:
  1. Add the weblogicx-gzip.jar file from the code download into your WAR's WEB-INF/lib directory.
  2. Register the gzip filter in your web.xml as shown in the WEB-INF/web.xml:
    <filter>
      <filter-name>GZIPFilter</filter-name>
      <filter-class>weblogicx.servlet.gzip.filter.GZIPFilter</filter-class>
    </filter>
  3. Map the filter like this (An example is also shown in the web.xml included with the code download):
    <filter-mapping>
       <filter-name>GZIPFilter</filter-name>
       <url-pattern>/*.html</url-pattern>
       <url-pattern>/service/wsdl/*</url-pattern>
    </filter-mapping>

PlanetJ Compression Filter

This compression filter is set up in almost an identical way as the WebLogic compression filter. You need to include the JAR and update the web.xml. Here is an example of the web.xml settings for the PlanetJ filter:
<filter>
      <filter-name>CompressingFilter</filter-name>
      <filter-class>com.planetj.servlet.filter.compression.CompressingFilter</filter-class>
      <init-param>
         <param-name>debug</param-name>
         <param-value>true</param-value>
      </init-param>
      <init-param>
         <param-name>jakartaCommonsLogger</param-name>
         <param-value>com.planetj.servlet.filter.compression.CompressingFilter</param-value>
      </init-param>
</filter>
<filter-mapping>
      <filter-name>CompressingFilter</filter-name>
      <url-pattern>/service/wsdl/*</url-pattern>
</filter-mapping>

Testing Compression of Web Services with soapUI

For testing purposes, compression filters were used to compress web service responses. This included XML in the SOAP envelope. The royalty-free, web service analysis and testing tool soapUI was used to test compressed web services (see Figure 2).


Figure 2. Setting soapUI Global Preferences: The soapUI tool allows global preference settings.

Among its many features, soapUI lets you receive compressed messages and automatically decompress them. Optionally, you may disable decompression, which is useful if you need to measure pure network transfer time without any processing on the client (see Figure 3).


Figure 3. Configuring soapUI to Disable Decompression: For testing, soapUI was configured to disable decompression of the incoming responses.

The test results from soapUI indicate that compression is comparable with both toolkits. In other words, the compressed output to uncompressed input has exactly the same ratio in both approaches. This is likely due to the fact that the algorithm is the same. Interestingly, the PlanetJ compression filter seems to compress faster than the WebLogic filter, which caused more request/response processing per specific amount of time. The table below shows the results of a sample 10-minute run.

Applying Compression Implementations

The advent of modern APIs for client/server communication leads to faster development times and more robust applications on one hand, but it can also lead to excessive messages transmitted over the wire on the other hand. This in turn requires you to apply other technologies, such as the compression implementations described in this article.

Code Download

  • JavaEE_Responce_Compresson.zip

    For Further Reading

  • Class CompressingFilter Documentation

    About the Author

    Vlad Kofman works on enterprise-scale projects for major Wall Street firms. He has also worked on defense contracts for the U.S. government. His main interests are web-related programming methodologies, UI patterns, and SOA.

  • Sitemap | Contact Us

    Thanks for your registration, follow us on our social networks to keep up-to-date