欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

servlet 以 gzip 格式返回数据

程序员文章站 2022-06-05 18:28:50
...
servlet 以 gzip 格式 返回结果

servlet 可以通过 gzip 格式返回结果,前提是 浏览器支持 gzip 格式,

------
gzip 格式返回数据的 步骤:

* 判断浏览器是否支持 gzip 格式
根据 header 中的 accept-encoding 属性 是否包含 "gzip" 字符 进行判定,
* 设置 返回的编码为 gzip 格式
设置 header 的 content-encoding 属性 的值为 "gzip",
* 创建支持 gzip 格式的输出流对象
可以通过 GZIPOutputStream 这个适配器类 创建 PrintWriter 对象,实现 gzip 格式输出,
例子:
PrintWriter pw = new PrintWriter(new GZIPOutputStream(resp.getOutputStream()));
* 输出内容
* 关闭 输出流
一定要调用 PrintWriter 对象的 close() 方法关闭输出流,否则 数据不能返回到浏览器端,
*

------
servlet gzip 工具类

* 逻辑:
提供2个方法:
* 判断浏览器是否支持 gzip 压缩
* 返回支持 gzip 压缩的 PrinterWriter 对象,如果浏览器不支持 gzip 则返回普通的 PrinterWriter 对象,
*

* 工具类 代码:
ServletGzipUtil.java

	package eric.servlet.util;
	import java.io.IOException;
	import java.io.PrintWriter;
	import java.util.zip.GZIPOutputStream;
	import javax.servlet.http.HttpServletRequest;
	import javax.servlet.http.HttpServletResponse;
	/**
	 * servlet 的 gzip 工具类
	 * @author eric
	 * @date 2010-9-14 下午07:53:20
	 */
	public class ServletGzipUtil {
		/**
		 * 判断浏览器是否支持 gzip 压缩
		 * @param req
		 * @return boolean 值
		 */
		public static boolean isGzipSupport(HttpServletRequest req) {
			String headEncoding = req.getHeader("accept-encoding");
			if (headEncoding == null || (headEncoding.indexOf("gzip") == -1)) { // 客户端 不支持 gzip
				return false;
			} else { // 支持 gzip 压缩
				return true;
			}
		}

		/**
		 * 创建 以 gzip 格式 输出的 PrintWriter 对象,如果浏览器不支持 gzip 格式,则创建普通的 PrintWriter 对象,
		 * @param req
		 * @param resp
		 * @return
		 * @throws IOException
		 */
		public static PrintWriter createGzipPw(HttpServletRequest req, HttpServletResponse resp) throws IOException {
			PrintWriter pw = null;
			if (isGzipSupport(req)) { // 支持 gzip 压缩
				pw = new PrintWriter(new GZIPOutputStream(resp.getOutputStream()));
				// 在 header 中设置返回类型为 gzip
				resp.setHeader("content-encoding", "gzip");
			} else { // // 客户端 不支持 gzip
				pw = resp.getWriter();
			}
			return pw;
		}
	}


------
firefox 中查看 gzip 结果:
在 firebug 中可以通过 网络 tab 看到 请求的细节,
可以看到 响应头信息 中的 Content-Encoding 值为 gzip,且 Content-Length 的值比不使用 gzip 时要小,

------
例子:

      * 代码写在 servlet 中

		protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
			PrintWriter pw = null;
			// gzip test
			String headEncoding = req.getHeader("accept-encoding");
			if (headEncoding == null || (headEncoding.indexOf("gzip") == -1)) { // 客户端 不支持 gzip
				pw = resp.getWriter();
			} else { // 支持 gzip 压缩
				pw = new PrintWriter(new GZIPOutputStream(resp.getOutputStream()));
				resp.setHeader("content-encoding", "gzip");	
			}

			pw.write("<table>");
			pw.write("<tr><td>name:</td><td>" + name + "</td></tr>");
			pw.write("<tr><td>sex:</td><td>" + sex + "</td></tr>");
			pw.write("<tr><td>habits:</td><td>" + Arrays.toString(habits) + "</td></tr>");
			pw.write("</table>");
			pw.write("&gt;&lt;&and;");
			// 这里一定要关闭
			pw.close();
		}

      * 使用 工具类 的 servlet:

		protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
			PrintWriter pw = ServletGzipUtil.createGzipPw(req, resp);
			pw.write("<table>");
			pw.write("<tr><td>name:</td><td>" + name + "</td></tr>");
			pw.write("<tr><td>sex:</td><td>" + sex + "</td></tr>");
			pw.write("<tr><td>habits:</td><td>" + Arrays.toString(habits) + "</td></tr>");
			pw.write("</table>");
			pw.write("&gt;&lt;&and;");
			// 这里一定要关闭
			pw.close();
		}


------