gzip是GNUzip的缩写,它是一个GNU自由软件的文件压缩程序。GZIP最早由Jean-loup Gailly和Mark Adler创建,用于UNIX系统的文件压缩。我们在Linux中经常会用到后缀为.gz的文件,它们就是GZIP格式的。现今已经成为Internet 上使用非常普遍的一种数据压缩格式,或者说一种文件格式。gzip文本压缩方案能够极大的减少HTML页面或者纯文本的大小,大多数浏览器都知道如何处理gzip压缩后的内容,支持这种功能的浏览器会设置Accept-Encoding请求报头;
下面我们看一个简单的demo实现:
package ServletReview; import java.io.IOException; import java.io.PrintWriter; import java.util.zip.GZIPOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class GzipUtils { // 根据报头来判断浏览器是否支持gzip解压缩功能 public static boolean isGzipSupported(HttpServletRequest request) { String encodings = request.getHeader("Accept-Encoding"); return ((encodings != null) && (encodings.indexOf("gzip") != -1)); } // 判断gzip功能是否已经启用 public static boolean isGzipDisabled(HttpServletRequest request) { String flag = request.getParameter("disableGzip"); return ((flag != null) && (!flag.equalsIgnoreCase("false"))); } //返回gzip压缩后的PrintWriter public static PrintWriter getGzipWriter(HttpServletResponse response){ try { return (new PrintWriter(new GZIPOutputStream(response.getOutputStream()))); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } } }
package ServletReview; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class LongServlet extends HttpServlet { /** * Servlet使用gzip压缩 */ private static final long serialVersionUID = 7807987641014318123L; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out; if (GzipUtils.isGzipSupported(request) && !GzipUtils.isGzipDisabled(request)) { out = GzipUtils.getGzipWriter(response); response.setHeader("Content-Encoding", "gzip"); } else { out = response.getWriter(); } StringBuffer stringBuffer = new StringBuffer(); stringBuffer.append("<table>"); for (int i = 0; i < 1000; i++) { stringBuffer.append("<tr><td>" + i + "</td></tr>"); } stringBuffer.append("</table>"); out.println(stringBuffer.toString()); out.close(); } }
<body> <% String path = request.getContextPath(); %> <form action="<%=path %>/longServlet" method="get"> <input type="submit" value="submit"> </form> </body>
<servlet> <servlet-name>LongServlet</servlet-name> <servlet-class>ServletReview.LongServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>LongServlet</servlet-name> <url-pattern>/longServlet</url-pattern> </servlet-mapping>
通过访问jsp页面输出:
0
1
2
3
...
另附Servlet Http请求报头列表,HTTP请求报头以及各自含义:
Accept:浏览器可接受的MIME类型。 Servlet检查Accept来确定使用哪种格式返回给客户端资源。 IE6和7 bug:重新载入页面发送的Accept报头不正确,但在最初的请求中是正确的。
Accept-Charset:浏览器可接受的字符集。
Accept-Encoding:浏览器能够进行解码的数据编码方式,比如gzip。 Servlet能够向支持gzip的浏览器返回经gzip编码的HTML页面。许多情形下这可以减少5到10倍的下载时间。 在使用任何类型的内容编码之前,一定要检查Accept-Dncoding报头。
Accept-Language:浏览器所希望的语言种类,当服务器能够提供一种以上的语言版本时要用到。
Authorization:授权信息,通常出现在对服务器发送的WWW-Authenticate头的应答中。
Connection:表示是否需要持久连接。 如果Servlet看到这里的值为“Keep-Alive”,或者看到请求使用的是HTTP 1.1(HTTP 1.1默认进行持久连接), 它就可以利用持久连接的优点,当页面包含多个元素时(例如Applet,图片),显著地减少下载所需要的时间。 要 实现这一点,Servlet需要在应答中发送一个Content-Length头, 最简单的实现方法是:先把内容写入 ByteArrayOutputStream,然后在正式写出内容之前计算它的大小。
Content-Length:表示请求消息正文的长度。
Cookie:这是最重要的请求头信息之一。
From:请求发送者的email地址,由一些特殊的Web客户程序使用,浏览器不会用到它。
Host:初始URL中的主机和端口。
If-Modified-Since:只有当所请求的内容在指定的日期之后又经过修改才返回它,否则返回304“Not Modified”应答。
Pragma:指定“no-cache”值表示服务器必须返回一个刷新后的文档,即使它是代理服务器而且已经有了页面的本地拷贝。
Referer:包含一个URL,用户从该URL代表的页面出发访问当前请求的页面。
User-Agent:浏览器类型,如果Servlet返回的内容与浏览器类型有关则该值非常有用。 在不要的时候才使用User-Agent。 在使用的时候要检查是否为null。 区分Netscape和IE 要检查MSIE 而非"Mozilla"。 这个报头可以加造而servlet并不能区分这种情况。
UA-Pixels,UA-Color,UA-OS,UA-CPU:由某些版本的IE浏览器所发送的非标准的请求头,表示屏幕大小、颜色深度和CPU类型。
out.println("Protocol: " + request.getProtocol()); out.println("Scheme: " + request.getScheme()); out.println("Server Name: " + request.getServerName() ); out.println("Server Port: " + request.getServerPort()); out.println("Protocol: " + request.getProtocol()); out.println("Server Info: " + getServletConfig().getServletContext().getServerInfo()); out.println("Remote Addr: " + request.getRemoteAddr()); out.println("Remote Host: " + request.getRemoteHost()); out.println("Character Encoding: " + request.getCharacterEncoding()); out.println("Content Length: " + request.getContentLength()); out.println("Content Type: "+ request.getContentType()); out.println("Auth Type: " + request.getAuthType()); out.println("HTTP Method: " + request.getMethod()); out.println("Path Info: " + request.getPathInfo()); out.println("Path Trans: " + request.getPathTranslated()); out.println("Query String: " + request.getQueryString()); out.println("Remote User: " + request.getRemoteUser()); out.println("Session Id: " + request.getRequestedSessionId()); out.println("Request URI: " + request.getRequestURI()); out.println("Servlet Path: " + request.getServletPath()); out.println("Accept: " + request.getHeader("Accept")); out.println("Host: " + request.getHeader("Host")); out.println("Referer : " + request.getHeader("Referer")); out.println("Accept-Language : " + request.getHeader("Accept-Language")); out.println("Accept-Encoding : " + request.getHeader("Accept-Encoding")); out.println("User-Agent : " + request.getHeader("User-Agent")); out.println("Connection : " + request.getHeader("Connection")); out.println("Cookie : " + request.getHeader("Cookie")); out.println("Created : " + session.getCreationTime()); out.println("LastAccessed : " + session.getLastAccessedTime());