1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

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

        共 26618字,需瀏覽 54分鐘

         ·

        2021-07-19 16:26

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

        通過請求和響應頭中增加

        Accept-Encoding: gzip
        Content-Encodin: gzip

        確定客戶端或服務器端是否支持壓縮

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

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

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

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

        客戶端也可以發(fā)送壓縮數(shù)據(jù)給服務端,通過代碼將請求數(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引導類

        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:測試驗證

        • 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類攔截響應,自動處理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
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            中国美女美穴 | 国产逼| 无码中文字幕一区二区免费蜜桃 | AV老鸭窝 | 国产精品久久久久久久久非色 | 超碰97老师 | 玩弄牲欲强老熟女tp121cc | 全黄一级裸片视频在线观看 | 日本屄视频 | 尻屄电影|