10.2. Data Compression

Data compression is a technique that packs the data from its raw format into compact bundles, thereby reducing its size. There are many algorithms available for compressing data. One of the most popular of these is the "deflate" algorithm, which is a combination of Lempel-Ziv (LZ) 77 and Huffman encoding. The GNU zip, better known as gzip, is based on this algorithm. If you desire to read more about gzip and the algorithms it's based on, then the Wikipedia page on the topic, accessible online at http://en.wikipedia.org/wiki/Gzip, would be a good starting point.

BlazeDS, as you know well, is a Java Servlets–based web application. As data from a BlazeDS server leaves for the Flex client, it can be intercepted using the familiar Java Servlet filter mechanism that you saw in action earlier in Chapter 7. Servlet filters can intercept requests to and responses from a Java Servlet.

In order to gzip the data transferred from the server to the client, I create a filter to manipulate and compress the outgoing response. Then I configure it for my BlazeDS instance. I don't need any changes in the BlazeDS code. Destinations called by the Flex client that return the data are totally unaware of this filter.

To get started and gain an understanding of how the filter works, first browse through the filter code in Listing 10-1.

Example 10.1. GzipFilter Java Source
package dsadapters.filters.gzip;
//Import statements -- available in the code download but removed to avoid
superfluous code listing
public class GzipFilter implements Filter
{
    public GzipFilter()
    {
    }

    @Override
    public void destroy()
    {
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse
    servletResponse,
            FilterChain filterChain) throws IOException, ServletException
    {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        HttpSession session = request.getSession(true);

        String gzip = request.getParameter("gzip");
        String ae = request.getHeader("accept-encoding");
        if ((ae != null) && (ae.indexOf("gzip") != −1) && (gzip != null))
        {

GzipResponseWrapper wrappedResponse = new GzipResponseWrapper(response);
          filterChain.doFilter(servletRequest, wrappedResponse);
          wrappedResponse.finishResponse();
        }
        else
        {
          filterChain.doFilter(servletRequest, servletResponse);
        }
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException
    {
        servletContext = filterConfig.getServletContext();
    }

    private ServletContext servletContext;
}

The main method of a filter class is the doFilter method. The doFilter method calls the filter with the request and response pair and calls the next filter in the chain till it reaches the end of the chain. In the GzipFilter class, the response is wrapped up and sent to the doFilter method. The response wrapper is the class that facilitates gzip compression of the outgoing response.

To dig deeper into the response wrapper and see how the gzip compression takes place, you may want to peek into the GzipResponseWrapper source, which is available in the code download bundle. Here, though, I will illustrate only the salient features of that class.

The Java Servlet 2.3 specification provides for two classes, javax.servlet.ServletResponseWrapper and javax.servlet.http.HttpServletResponseWrapper, that provide a mechanism to override the standard response object behavior. A similar set of wrapper classes exists for overriding the standard request object as well. The GzipResponseWrapper class extends HttpServletResponseWrapper. It creates a stand in stream and writes compressed data to it. The stream class itself is called GzipResponseStream. GzipResponseStream extends ServletResponseStream and uses the java.util.zip.GZIPOutputStream utility class to compress the byte array output stream and then write it to the output that the browser receives.

To use the GzipFilter with BlazeDS, add the compiled classes to WEB-INF/classes (if packaged as independent .class files) or WEB-INF/lib (if packaged as a jar archive file) folder the following configuration to web.xml:

<filter>
      <filter-name>GzipFilter</filter-name>
      <filter-class>dsadapters.filters.GzipFilter</filter-class>
      <init-param>
          <!-- debug prints size and other information to the console -->
          <param-name>debug</param-name>
          <param-value>true</param-value>
      </init-param>
      <init-param>
          <!-- The minimum size, in bytes, for when to start using compression. -->
          <!-- Responses below this threshold are sent without compression.  -->

<param-name>minimumSize</param-name>
          <param-value>1000</param-value>
      </init-param>
    </filter>

    <!-- This mapping enables gzip compression for RemoteObject -->
    <filter-mapping>
      <filter-name>GzipFilter</filter-name>
      <servlet-name>AMFGatewayServlet</servlet-name>
    </filter-mapping>

    <!-- This mapping enables gzip compression for WebService and HTTPService -->
    <filter-mapping>
      <filter-name>GzipFilter</filter-name>
      <servlet-name>FlexProxyServlet</servlet-name>
    </filter-mapping>

At this point, I am certain that you are convinced that compressing data is fairly easy and straightforward. While compression can be applied to any data format, text or binary, and size, the effect is quite different, depending on the data format and size.

Next, a few data formats and their impact on application performance and scalability are analyzed.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.226.66