一. HTTP gzip压缩,概述
- request
- header中声明Accept-Encoding : gzip,告知服务器客户端接受gzip的数据
- response
- body,同时加入以下header:Content-Encoding: gzip:表明body是gzip过的数据
- Content-Length:117:表示body gzip压缩后的数据大小,便于客户端使用
- 或Transfer-Encoding: chunked:分块传输编码
tomcat server.xml
<Connectorcompression="on" # 表示开启压缩noCompressionUserAgents="gozilla, traviata"compressionMinSize="2048" # 表示会对大于2KB的文件进行压缩compressableMimeType="text/html,text/xml,text/css,text/JAVAscript,image/gif,image/jpg" # 是指将进行压缩的文件类型/>
- 弊端
对HTTP传输内容进行压缩是改良前端响应性能的可用方法之一,大型网站都在用 。但是也有缺点,就是压缩过程占用cpu的资源,客户端浏览器解析也占据了一部分时间 。但是随着硬件性能不断的提高,这些问题正在不断的弱化 。
GZIPInputStream(解压) / GZIPOutputStream(压缩)
- netflix.zuul相关示例
# org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter#writeResponse()is = context.getResponseDataStream();InputStream inputStream = is;if (is != null) {if (context.sendZuulResponse()) {// if origin response is gzipped, and client has not requested gzip,// decompress stream// before sending to client// else, stream gzip directly to clientif (context.getResponseGZipped() && !isGzipRequested) {// If origin tell it's GZipped but the content is ZERO bytes,// don't try to uncompressfinal Long len = context.getOriginContentLength();if (len == null || len > 0) {try {inputStream = new GZIPInputStream(is);}catch (java.util.zip.ZipException ex) {log.debug("gzip expected but not "+ "received assuming unencoded response "+ RequestContext.getCurrentContext().getRequest().getRequestURL().toString());inputStream = is;}}else {// Already done : inputStream = is;}}else if (context.getResponseGZipped() && isGzipRequested) {servletResponse.setHeader(ZuulHeaders.CONTENT_ENCODING, "gzip");}writeResponse(inputStream, outStream);}}# com.netflix.zuul.http.HttpServletRequestWrApper.UnitTest#handlesGzipRequestBody@Testpublic void handlesGzipRequestBody() throws IOException {// creates string, gzips into byte array which will be mocked as InputStream of requestfinal String body = "hello";final byte[] bodyBytes = body.getBytes();// in this case the compressed stream is actually larger - need to allocate enough spacefinal ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream(0);final GZIPOutputStream gzipOutStream = new GZIPOutputStream(byteOutStream);gzipOutStream.write(bodyBytes);gzipOutStream.finish();gzipOutStream.flush();body(byteOutStream.toByteArray());final HttpServletRequestWrapper wrapper = new HttpServletRequestWrapper(request);assertEquals(body, IOUtils.toString(new GZIPInputStream(wrapper.getInputStream())));}
示例: 网关主动对response进行压缩响应(可减少带宽) GZIPOutputStream- 简单实现示例.实际情况需考虑更新情况,如是否已经被压缩等
InputStream inputStream = okResponse.body().byteStream();try {// 网关主动对response进行压缩响应(可减少带宽)HttpServletRequest request = RequestContext.getCurrentContext().getRequest();boolean isGatewayGZIP = Boolean.parseBoolean(request.getHeader("x-gateway-gzip"));if (!isGatewayGZIP) {isGatewayGZIP = Boolean.parseBoolean(request.getParameter("x-gateway-gzip"));}if (isGatewayGZIP) {final ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream(0);final GZIPOutputStream gzipOutStream = new GZIPOutputStream(byteOutStream);gzipOutStream.write(okResponse.body().bytes());gzipOutStream.finish();gzipOutStream.flush();inputStream = new ServletInputStreamWrapper(byteOutStream.toByteArray());httpHeaders.add(ZuulHeaders.CONTENT_ENCODING, "gzip");}} catch (Exception e) {logger.error("GatewayGZIP error:", e);}
三.okhttp 压缩相关处理okHttp 解压gzip,条件: Content-Encoding = gizp- okio.GzipSource
if (transparentGzip&& "gzip".equalsIgnoreCase(networkResponse.header("Content-Encoding"))&& HttpHeaders.hasBody(networkResponse)) { GzipSource responseBody = new GzipSource(networkResponse.body().source()); Headers strippedHeaders = networkResponse.headers().newBuilder().removeAll("Content-Encoding").removeAll("Content-Length").build(); responseBuilder.headers(strippedHeaders); String contentType = networkResponse.header("Content-Type"); responseBuilder.body(new RealResponseBody(contentType, -1L, Okio.buffer(responseBody)));}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- netty系列之:性能为王!创建多路复用http2服务器
- 长链接、短链接与连接池
- Linux上使用tinyproxy快速搭建HTTP/HTTPS代理器
- wireshark 如何抓包https
- 2021年年度最佳开源软件
- 面试官问 HTTPS 是怎么从 HTTP 转过来的,我有点懵
- gif图片太大怎么压缩?动图压缩超容易
- 视频怎么压缩变小?教你学会压缩视频
- pdf格式怎么压缩变小?三步就可完成pdf的压缩
- PPT太大怎么压缩变小?不如用这几招来压缩PPT