<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          SpringBoot 壓縮數(shù)據(jù)流如何解壓

          共 26618字,需瀏覽 54分鐘

           ·

          2021-07-19 16:26

          0x01:HTTP壓縮數(shù)據(jù)傳輸簡介

          通過請求和響應(yīng)頭中增加

          Accept-Encoding: gzip
          Content-Encodin: gzip

          確定客戶端或服務(wù)器端是否支持壓縮

          舉例,客戶端發(fā)送請求,服務(wù)端壓縮響應(yīng)數(shù)據(jù)返給客戶端

          • 客戶端請求中增加 Accept-Encoding: gzip 表示客戶端支持gzip;

          • 服務(wù)端接收到請求后,將結(jié)果通過 gzip 壓縮后返回給客戶端并在響應(yīng)頭中增加 Content-Encoding: gzip 表示響應(yīng)數(shù)據(jù)已被壓縮

          • 客戶端接收請求,響應(yīng)頭中有 Content-Encoding: gzip 表示數(shù)據(jù)需解壓處理

          客戶端也可以發(fā)送壓縮數(shù)據(jù)給服務(wù)端,通過代碼將請求數(shù)據(jù)壓縮即可,規(guī)范起見同樣要在請求中加入 Content-Encoding: gzip


          0x02:SpringBoot 案例

          pom.xml 引入如下依賴

          <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

              <modelVersion>4.0.0</modelVersion>

              <groupId>com.iothw</groupId>
              <artifactId>gzip-demo</artifactId>
              <version>0.0.1-SNAPSHOT</version>
              <packaging>jar</packaging>

              <name>gzip-demo</name>
              <url>http://maven.apache.org</url>

              <properties>
                  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
                  <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
                  <java.version>1.8</java.version>
                  <spring-cloud.version>Finchley.SR2</spring-cloud.version>
                  <mybatis.version>1.3.0</mybatis.version>
              </properties>

              <parent>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-parent</artifactId>
                  <version>2.3.0.RELEASE</version>
                  <relativePath /> <!-- lookup parent from repository -->
              </parent>

              <dependencies>
                  <dependency>
                      <groupId>org.springframework.boot</groupId>
                      <artifactId>spring-boot-starter-web</artifactId>
                  </dependency>
                  <dependency>
                      <groupId>org.projectlombok</groupId>
                      <artifactId>lombok</artifactId>
                      <version>1.16.18</version>
                  </dependency>

              </dependencies>

              <dependencyManagement>
                  <dependencies>
                      <dependency>
                          <groupId>org.springframework.boot</groupId>
                          <artifactId>spring-boot-starter-parent</artifactId>
                          <version>2.3.0.RELEASE</version>
                          <type>pom</type>
                          <scope>import</scope>
                      </dependency>
                  </dependencies>
              </dependencyManagement>

              <build>
                  <plugins>
                      <plugin>
                          <groupId>org.springframework.boot</groupId>
                          <artifactId>spring-boot-maven-plugin</artifactId>
                      </plugin>
                  </plugins>
              </build>
              <repositories>
                  <repository>
                      <id>aliyunmaven</id>
                      <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
                  </repository>
              </repositories>
          </project>

          編寫Gzip解壓過濾器

          package com.iothw.gzip.filter;

          import java.io.ByteArrayInputStream;
          import java.io.ByteArrayOutputStream;
          import java.io.IOException;
          import java.util.zip.GZIPInputStream;

          import javax.servlet.Filter;
          import javax.servlet.FilterChain;
          import javax.servlet.FilterConfig;
          import javax.servlet.ReadListener;
          import javax.servlet.ServletException;
          import javax.servlet.ServletInputStream;
          import javax.servlet.ServletRequest;
          import javax.servlet.ServletResponse;
          import javax.servlet.annotation.WebFilter;
          import javax.servlet.http.HttpServletRequest;

          import lombok.extern.slf4j.Slf4j;

          /**
           * GZIP處理Filter
           */

          @WebFilter(filterName = "gzipFilter", urlPatterns = "/")
          public class GzipFilter implements Filter {

              @Override
              public void destroy() {
              }

              @Override
              public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                      throws IOException, ServletException 
          {
                  chain.doFilter(new HttpServletRequestWrapper((HttpServletRequest) request), response);
              }

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

          @Slf4j
          class HttpServletRequestWrapper extends javax.servlet.http.HttpServletRequestWrapper {
              private HttpServletRequest request;

              public HttpServletRequestWrapper(HttpServletRequest request) {
                  super(request);
                  this.request = request;
              }

              /**
               * 根據(jù) request header 的 Content-Encoding 判斷是否啟用 gzip 解壓數(shù)據(jù)流
               */

              @Override
              public ServletInputStream getInputStream() throws IOException {
                  ServletInputStream stream = request.getInputStream();
                  String contentEncoding = request.getHeader("Content-Encoding");
                  if (null != contentEncoding && contentEncoding.indexOf("gzip") != -1) {
                      GZIPInputStream gzipInputStream = new GZIPInputStream(stream);
                      try {
                          ByteArrayOutputStream bout = new ByteArrayOutputStream();
                          int len = -1;
                          byte[] buffer = new byte[128];
                          while((len = gzipInputStream.read(buffer))!=-1){
                              bout.write(buffer, 0, len);
                          }
                          ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
                          ServletInputStream newStream = new ServletInputStream() {
                              @Override
                              public int read() throws IOException {
                                  return bin.read();
                              }

                              @Override
                              public boolean isFinished() {
                                  return false;
                              }

                              @Override
                              public boolean isReady() {
                                  return false;
                              }

                              @Override
                              public void setReadListener(ReadListener readListener) {
                              }
                          };
                          return newStream;
                      } catch (Exception e) {
                          log.error("uncompress content fail", e);
                      }finally{
                          try {
                              gzipInputStream.close();
                          } catch (Exception e) {
                          }
                      }
                  }

                  return stream;
              }
          }

          注冊過濾器

          package com.iothw.gzip.config;

          import java.util.ArrayList;
          import java.util.List;

          import javax.servlet.Filter;

          import org.springframework.boot.web.servlet.FilterRegistrationBean;
          import org.springframework.context.annotation.Bean;
          import org.springframework.context.annotation.Configuration;

          import com.iothw.gzip.filter.GzipFilter;

          @Configuration
          public class FilterConfig {
              /**
               * 注冊 GzipFilter
               *
               * @return
               */

              @Bean
              public FilterRegistrationBean<Filter> filterRegistrationBean() {
                  FilterRegistrationBean<Filter> registrationBean = new FilterRegistrationBean<Filter>();
                  registrationBean.setFilter(new GzipFilter());

                  List<String> urlPatterns = new ArrayList<>();
                  urlPatterns.add("/*");
                  registrationBean.setUrlPatterns(urlPatterns);

                  return registrationBean;
              }
          }

          編寫SpringBoot引導(dǎo)類

          package com.iothw.gzip;

          import org.springframework.boot.SpringApplication;
          import org.springframework.boot.autoconfigure.SpringBootApplication;


          @SpringBootApplication
          public class Application {
              public static void main( String[] args ){
                  SpringApplication.run(Application.class, args);
              }
          }


          0x03:測試驗(yàn)證

          • okhttp

          引入依賴

          <dependency>
              <groupId>com.squareup.okhttp3</groupId>
              <artifactId>okhttp</artifactId>
              <version>4.4.1</version>
          </dependency>

          測試類

          package com.test;

          import java.io.IOException;

          import okhttp3.Interceptor;
          import okhttp3.MediaType;
          import okhttp3.OkHttpClient;
          import okhttp3.Request;
          import okhttp3.RequestBody;
          import okhttp3.Response;
          import okio.BufferedSink;
          import okio.GzipSink;
          import okio.Okio;

          public class OkHttpGzipTest {

              public void processPost() {
                  String url = "http://localhost:8080/gzip/gzipTest";
                  String str = "我是要被壓縮上傳的數(shù)據(jù),看好了我是壓縮的數(shù)據(jù)";
                  try {
                      String response = post(url, str);
                      System.out.println(response);
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }

              public String post(String url, String json) throws IOException {
                  OkHttpClient client = new OkHttpClient.Builder()
                          // 通過GzipRequestInterceptor類攔截響應(yīng),自動(dòng)處理gzip解壓
                          .addInterceptor(new GzipRequestInterceptor())
                          .build();
                  MediaType JSON = MediaType.get("application/json; charset=utf-8");
                  RequestBody body = RequestBody.create(json, JSON);
                  Request request = new Request.Builder()
                          .url(url)
                          .post(body)
                          .build();
                  try (Response response = client.newCall(request).execute()) {
                      return response.body().string();
                  }
              }

              class GzipRequestInterceptor implements Interceptor {
                  @Override
                  public Response intercept(Chain chain) throws IOException {
                      Request originalRequest = chain.request();
                      if (originalRequest.body() == null || originalRequest.header("Content-Encoding") != null) {
                          return chain.proceed(originalRequest);
                      }

                      Request compressedRequest = originalRequest.newBuilder()
                              .header("Content-Encoding""gzip")
                              .method(originalRequest.method(), gzip(originalRequest.body()))
                              .build();
                      return chain.proceed(compressedRequest);
                  }

                  private RequestBody gzip(final RequestBody body) {
                      return new RequestBody() {
                          @Override
                          public MediaType contentType() {
                              return body.contentType();
                          }

                          @Override
                          public long contentLength() {
                              // We don't know the compressed length in advance!
                              return -1;
                          }

                          @Override
                          public void writeTo(BufferedSink sink) throws IOException {
                              BufferedSink gzipSink = Okio.buffer(new GzipSink(sink));
                              body.writeTo(gzipSink);
                              gzipSink.close();
                          }
                      };
                  }
              }

              public static void main(String[] args) {
                  OkHttpGzipTest gt = new OkHttpGzipTest();
                  gt.processPost();
              }
          }
          • httpclient

          引入依賴

          <dependency>
              <groupId>org.apache.httpcomponents</groupId>
              <artifactId>httpclient</artifactId>
              <version>4.5.10</version>
          </dependency>

          測試類

          package com.test;

          import java.io.ByteArrayOutputStream;
          import java.io.IOException;
          import java.nio.charset.Charset;
          import java.util.zip.GZIPOutputStream;

          import org.apache.http.HttpResponse;
          import org.apache.http.client.ClientProtocolException;
          import org.apache.http.client.HttpClient;
          import org.apache.http.client.methods.HttpPost;
          import org.apache.http.entity.ByteArrayEntity;
          import org.apache.http.impl.client.DefaultHttpClient;
          import org.apache.http.util.EntityUtils;

          public class HttpClientGzipTest {

              /**
               * gzip 壓縮發(fā)送
               */

              public void sendHttp(String url, String message) throws ClientProtocolException, IOException {
                  HttpClient httpClient = new DefaultHttpClient();
                  HttpPost httpPost = new HttpPost(url);
                  httpPost.setHeader("Content-Encoding""gzip");
                  try {
                      ByteArrayOutputStream originalContent = new ByteArrayOutputStream();
                      originalContent.write(message.getBytes(Charset.forName("UTF-8")));
                      ByteArrayOutputStream baos = new ByteArrayOutputStream();
                      GZIPOutputStream gzipOut = new GZIPOutputStream(baos);
                      originalContent.writeTo(gzipOut);
                      gzipOut.finish();
                      httpPost.setEntity(new ByteArrayEntity(baos.toByteArray()));
                  } catch (Exception e) {
                      e.printStackTrace();
                  }
                  HttpResponse httpResponse = httpClient.execute(httpPost);
                  if (httpResponse.getStatusLine().getStatusCode() == 200) {
                      System.out.println(EntityUtils.toString(httpResponse.getEntity()));
                  }
              }

              public static void main(String[] args) {
                  HttpClientGzipTest ht = new HttpClientGzipTest();

                  String url = "http://localhost:8080/gzip/gzipTest";
                  String message = "我是要被壓縮上傳的數(shù)據(jù),看好了我是壓縮的數(shù)據(jù)";

                  try {
                      ht.sendHttp(url, message);
                  } catch (Exception e) {
                      e.printStackTrace();
                  }
              }
          }

          喜歡,在看



          瀏覽 156
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  wwwCn一起操 | 第九色综合| 91成人视频一区二区三区在线观看 | 操B在线观看视频 | 成人蘑菇 www网站 |