View Javadoc

1   /**
2    *  Copyright 2003-2007 Greg Luck
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   */
16  
17  package net.sf.ehcache.constructs.web.filter;
18  
19  import net.sf.ehcache.constructs.web.AlreadyGzippedException;
20  import net.sf.ehcache.constructs.web.GenericResponseWrapper;
21  import net.sf.ehcache.constructs.web.PageInfo;
22  
23  import javax.servlet.FilterChain;
24  import javax.servlet.http.HttpServletRequest;
25  import javax.servlet.http.HttpServletResponse;
26  import java.io.ByteArrayOutputStream;
27  import java.io.IOException;
28  
29  
30  /**
31   * A Template for a page caching filter that is designed for "included" pages, eg: jsp:includes.  This filter
32   * differs from the {@link CachingFilter} in that it is not writing an entire response to the output stream.
33   * <p/>
34   * This class should be sub-classed for each included page to be cached.
35   * <p/>
36   * Filter Mappings need to be set up for a cache to have effect.
37   *
38   * @author <a href="mailto:gluck@thoughtworks.com">Greg Luck</a>
39   * @version $Id: PageFragmentCachingFilter.java 512 2007-07-10 09:18:45Z gregluck $
40   */
41  public abstract class PageFragmentCachingFilter extends CachingFilter {
42  
43      /**
44       * Performs the filtering for a request.
45       */
46      protected void doFilter(final HttpServletRequest request, final HttpServletResponse response,
47                              final FilterChain chain) throws Exception {
48  
49          PageInfo pageInfo = buildPageInfo(request, response, chain);
50  
51          // Send the page to the client
52          writeResponse(response, pageInfo);
53      }
54  
55      /**
56       * {@inheritDoc}
57       *
58       * @param request {@inheritDoc}
59       * @param response {@inheritDoc}
60       * @param chain {@inheritDoc}
61       * @return {@inheritDoc}
62       * @throws AlreadyGzippedException {@inheritDoc}
63       * @throws Exception {@inheritDoc}
64       */
65      protected PageInfo buildPage(final HttpServletRequest request, final HttpServletResponse response,
66                                   final FilterChain chain) throws AlreadyGzippedException, Exception {
67  
68          // Invoke the next entity in the chain
69          final ByteArrayOutputStream outstr = new ByteArrayOutputStream();
70          final GenericResponseWrapper wrapper = new GenericResponseWrapper(response, outstr);
71          chain.doFilter(request, wrapper);
72          wrapper.flush();
73  
74          // Return the page info
75          return new PageInfo(wrapper.getStatus(), wrapper.getContentType(), wrapper.getHeaders(), wrapper.getCookies(),
76                  outstr.toByteArray(), false);
77      }
78  
79  
80      /**
81       * Assembles a response from a cached page include.
82       * These responses are never gzipped
83       * The content length should not be set in the response, because it is a fragment of a page.
84       * Don't write any headers at all.
85       */
86      protected void writeResponse(final HttpServletResponse response, final PageInfo pageInfo) throws IOException {
87          // Write the page
88          final byte[] cachedPage = pageInfo.getUngzippedBody();
89  
90          String implementationVendor = response.getClass().getPackage().getImplementationVendor();
91          if (implementationVendor != null && implementationVendor.equals("\"Evermind\"")) {
92          response.getOutputStream().write(cachedPage);
93          } else {
94              response.getWriter().write(new String(cachedPage));
95      }
96  }
97  }