Gzip压缩和缓存过滤器- 貝殼茶- JavaEye技术网站

这段时间一直在使用Page Speed测试页面,一直出现以下几个问题:

根据Google的建议,写了一个Filter来解决这三个问题,代码如下:

/*
 * GzipAndCacheFilter.java Jan 21, 2010 2:09:31 PM
 */
package org.shelltea.todo.web.filter;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.zip.GZIPOutputStream;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.ehcache.constructs.web.filter.FilterServletOutputStream;
import net.sf.ehcache.constructs.web.GenericResponseWrapper;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author shelltea
 * 
 */
public class GzipAndCacheFilter implements Filter {
	private static final Logger LOG = LoggerFactory
			.getLogger(GzipAndCacheFilter.class);

	@Override
	public void destroy() {
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		final HttpServletRequest httpRequest = (HttpServletRequest) request;
		final HttpServletResponse httpResponse = (HttpServletResponse) response;

		if (acceptsGzipEncoding(httpRequest)) {
			if (LOG.isDebugEnabled()) {
				LOG.debug("gzip:" + httpRequest.getRequestURL());
			}

			// 创建gzip stream
			final ByteArrayOutputStream compressed = new ByteArrayOutputStream();
			final GZIPOutputStream gzout = new GZIPOutputStream(compressed);

			// 处理request
			final GenericResponseWrapper wrapper = new GenericResponseWrapper(
					httpResponse, gzout);
			chain.doFilter(request, wrapper);
			wrapper.flush();

			gzout.close();

			int statusCode = wrapper.getStatus();
			if (statusCode != HttpServletResponse.SC_OK) {
				return;
			}

			byte[] compressedBytes = compressed.toByteArray();

			httpResponse.setHeader("Content-Encoding", "gzip");

			addCacheControl(httpResponse, httpRequest);

			response.setContentLength(compressedBytes.length);
			response.getOutputStream().write(compressedBytes);

		} else {
			chain.doFilter(request, response);
		}
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	}

	private boolean acceptsGzipEncoding(HttpServletRequest request) {
		return acceptsEncoding(request, "gzip");
	}

	private boolean acceptsEncoding(final HttpServletRequest request,
			final String name) {
		final boolean accepts = headerContains(request, "Accept-Encoding", name);
		return accepts;
	}

	private boolean headerContains(final HttpServletRequest request,
			final String header, final String value) {
		final Enumeration<?> accepted = request.getHeaders(header);
		while (accepted.hasMoreElements()) {
			final String headerValue = (String) accepted.nextElement();
			if (headerValue.indexOf(value) != -1) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 根据不同的资源采用不同的缓存策略
	 * 
	 * @param httpResponse
	 * @param httpRequest
	 */
	private void addCacheControl(HttpServletResponse httpResponse,
			HttpServletRequest httpRequest) {
		String URL = httpRequest.getRequestURL().toString();

		if (URL.charAt(URL.length() - 1) == '/') {
			httpResponse.setHeader("Cache-Control", "private, max-age=0");
			httpResponse.setHeader("Expires", "-1");
			return;
		}
		httpResponse.setHeader("Cache-Control", "public, max-age=31536000");
		httpResponse.setHeader("Vary", "Accept-Encoding");
	}
}

代码中的GenericResponseWrapper和FilterServletOutputStream是引用

在web.xml中加入此过滤器:

 <filter>
  <filter-name>GzipAndCache</filter-name>
  <filter-class>org.shelltea.todo.web.filter.GzipAndCacheFilter</filter-class>
 </filter>
 <filter-mapping>
  <filter-name>GzipAndCache</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>

?以下是使用此过滤器后的Page Speed分析结果:

?

?

郑重声明:资讯 【Gzip压缩和缓存过滤器- 貝殼茶- JavaEye技术网站】由 发布,版权归原作者及其所在单位,其原创性以及文中陈述文字和内容未经(企业库qiyeku.com)证实,请读者仅作参考,并请自行核实相关内容。若本文有侵犯到您的版权, 请你提供相关证明及申请并与我们联系(qiyeku # qq.com)或【在线投诉】,我们审核后将会尽快处理。
—— 相关资讯 ——