Spring Boot 与 Gzip 压缩

响应压缩是 Web 应用一种常见的优化手段,通过压缩算法减小传输数据的体积,提高传输效率、节约带宽。客户端接收到数据后,使用相同的算法对数据进行解压从而获取到原始数据。

客户端和服务器需要通过 Header 来协商双方支持的压缩算法。

  • Accept-Encoding:请求头,告诉服务器客户端支持的压缩算法(多个使用逗号分割)。例如:Accept-Encoding: gzip, deflate
  • Content-Encoding:响应头,告诉客户端当前 Payload 使用的编码方式(压缩算法)。例如:Content-Encoding: gzip

常用的压缩算法如下:

  • gzip
  • deflate
  • br

JDK 提供了对 GZIP 压缩算法的实现:GZIPOutputStream 和 GZIPInputStream,我们可以用它们来实现 Gzip 压缩和解压缩。

一、使用 Gzip 压缩响应

在 Spring Boot 应用中创建一个 Controller,使用 GZIPOutputStream 把一张图片文件(20 KB)压缩后响应给客户端。

package cn.springdoc.demo.web.controller;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Optional;
import java.util.zip.GZIPOutputStream;

import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;


@RestController
@RequestMapping("/demo")
public class DemoController {

    @GetMapping
    public void file (HttpServletRequest request, HttpServletResponse response) throws IOException {

        // 20.0 KB 大小的图片文件
        Path file = Paths.get("C:\\Users\\KevinBlandy\\Desktop\\springdoc-logo.png");
        
        // 设置文件类型
        response.setContentType(Optional.ofNullable(Files.probeContentType(file)).orElse(MediaType.APPLICATION_OCTET_STREAM_VALUE));
        
        // 设置压缩方式为 gzip 【关键点 1:设置正确的 CONTENT_ENCODING 头】
        response.setHeader(HttpHeaders.CONTENT_ENCODING, "gzip");
        
        // 包装 response 流为 gzip 流 【关键点 2:使用 GZIPOutputStream 封装 response 流,并写出数据】
        try(GZIPOutputStream gzipOutputStream = new GZIPOutputStream(response.getOutputStream())){
            // 响应给客户端
            Files.copy(file, gzipOutputStream);
        }
    }
}

如上。关键点在于设置 CONTENT_ENCODING Header 为 gzip,告诉浏览器使用了 gzip 压缩算法,浏览器会自动使用相同算法进行解压缩。

最后,使用 GZIPOutputStream 封装 response 流,往 gzipOutputStream 中写入的数据就会被 gzip 压缩。

启动应用,使用浏览器访问:http://localhost:8080/demo

Spring Boot Gzip 压缩响应

通过控制台的网络面板,你可以看到:

  1. 浏览器通过 Accept-Encoding 告诉服务器,它支持 gzip 压缩算法。
  2. 服务器正确地指定了 Payload 的编码类型为 gzip
  3. 由于使用了 Gzip 压缩,数据的传输体积小于文件体积。

图片在浏览器中预览成功,也说明服务器和客户端都进行了正确的编解码。

二、Spring Boot 配置响应压缩

对于这种如此常用的功能,Spring Boot 早已提供了开箱即用的支持。

可以在 application.yaml / application.properties 文件中配置如下属性,开启全局 Gzip 响应压缩:

属性

说明

默认值

server.compression.enabled

是否开启全局响应压缩

false

server.compression.excluded-user-agents

以逗号分隔的 User Agent 列表,对这些 User Agent 的响应不会被压缩。

server.compression.mime-types

逗号分割的文件 MIME Type(媒体类型),这些类型的文件才会被压缩。

[text/html, text/xml, text/plain, text/css, text/javascript, application/javascript, application/json, application/xml]

server.compression.min-response-size

进行压缩的最低 Content-Length 值。

2KB

在 application.yaml 中添加如下配置:

server:
  compression:
    # 开启响应压缩
    enabled: true
    mime-types: 
      - image/png # 压缩 png 图片
    # 进行压缩的最小体积
    min-response-size: 1KB

其实只需要设置 server.compression.enabled=true 即可,这里故意设置 server.compression.min-response-size=1KB 完全是为了进行演示,因为示例图片不足 2KB

server.compression.min-response-size 值不应该过小,否则压缩后的数据体积可能比原始数据还大。

还需要覆盖 server.compression.mime-types 配置,因为默认配置的压缩的文件类型列表中不包含图片。

修改 Controller,如下:

@GetMapping
public ResponseEntity<Resource> file (HttpServletRequest request, HttpServletResponse response) throws IOException {

    // 20.0 KB 大小的图片文件
    Path file = Paths.get("C:\\Users\\KevinBlandy\\Desktop\\springdoc-logo.png");
    
    return ResponseEntity.ok()
            .contentType(MediaType.IMAGE_PNG) // 正确设置图片的 Content Type,浏览器才会预览图片
            .body(new InputStreamResource(Files.newInputStream(file)));
}

这次不自己使用 GZIPOutputStream 进行压缩响应,而是直接返回 ResponseEntity<Resource> 对象。这也是关键点,如果你想基于配置的全局 Gzip 响应压缩生效,则不能自己使用 HttpServletResponse 进行数据响应,必须要通过返回对象,由 DispatcherServlet 处理,全局响应压缩才会生效。

重启应用,用浏览器再次请求 http://localhost:8080/demo,你会发现结果跟上节中的测试结果一样。全局 Gzip 压缩配置生效。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/171225.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

迎接“全全闪”时代 星辰天合发布星海架构和星飞产品

11 月 17 日&#xff0c;北京市星辰天合科技股份有限公司&#xff08;简称&#xff1a;XSKY星辰天合&#xff09;在北京首钢园举办了主题为“星星之火”的 XSKY 星海全闪架构暨星飞存储发布会&#xff0c;到场嘉宾共同见证了全新的分布式全闪架构“星海&#xff08;XSEA&#x…

企业办公室信息安全保密办法——推荐用天锐绿盾数据安全防泄密系统 | 防止核心文件数据、资料泄露

天锐绿盾数据安全防泄密系统是一种有效的办公室信息安全保密办法。该系统采用驱动层透明加密技术&#xff0c;对电子文件进行自动加密&#xff0c;保护数据的安全性和隐私性。 PC端访问地址&#xff1a; https://isite.baidu.com/site/wjz012xr/2eae091d-1b97-4276-90bc-6757c…

深搜回溯剪枝-全排列

LCR 083. 全排列 - 力扣&#xff08;LeetCode&#xff09; 根据题意&#xff0c;要根据给定的整数数组&#xff0c;穷举出所有可能的排列&#xff0c;从直观的角度上来看&#xff0c;可以使用多层 for 循环来解决&#xff0c;但如果是数组长度太大的时候&#xff0c;这种方式不…

利用Python进行中文分词——实现中文文本处理的基础工具

中文是一种复杂的语言&#xff0c;其词语之间没有明显的分隔符号&#xff0c;这给中文文本处理带来了一定的挑战。为了更好地处理中文文本数据&#xff0c;Python提供了许多优秀的中文分词工具和库。中文分词是将连续的中文文本切分成独立词语的过程&#xff0c;是中文文本处理…

『亚马逊云科技产品测评』活动征文|搭建图床chevereto

『亚马逊云科技产品测评』活动征文&#xff5c;搭建图床chevereto 提示&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 Developer Centre, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道 文章目录 『…

老师怎么才能让学生听话

在教育学生的过程中&#xff0c;如何让他们听话并且尊重师长&#xff0c;是一个老师需要深入思考的问题。这不仅涉及到学生的学习进步&#xff0c;还关系到他们的人格形成。以下是一些方法和策略&#xff0c;帮助教师更好地引导学生&#xff0c;使他们更愿意听从教导。 建立信任…

ubuntu从源码编译gdal

删除旧版本 sudo apt remove libgdal* sudo apt remove gdal* sudo apt autoremove下载proj和gdal https://github.com/OSGeo/PROJ/releases 这里使用的是9.3.0版本&#xff1a; https://github.com/OSGeo/gdal/releases 这里使用的是3.7.3版本&#xff1a; 编译 安装…

PLC设备相关常用英文单词(一)

PLC设备相关常用英文单词&#xff08;一&#xff09; Baud rate 波特率Bus 总线Binary 二进制Configuration 组态Consistent data 一致性数据Counter 计数器Cycle time 循环时间Conveyor 传送Device names 设备名称Debug 调试Download 下载Expand 扩展Fix 固定Flow 流量Functio…

万宾科技智能井盖的效果怎么样?

日常出行过程中&#xff0c;人们最不想看到交通拥堵或者道路维修等现象&#xff0c;因为这代表出行受到影响甚至会导致不能按时赴约等。所以城市路面的安全和稳定&#xff0c;是市民朋友非常关心的话题。骑行在路上的时候&#xff0c;如果经过井盖时发出异常声响&#xff0c;骑…

SVN 修改版本库地址url路径

一、win11用户 1. win11系统右链菜单比较优秀&#xff0c;如果菜单中选择“TortoiseSVN”找不到“重新定位”&#xff0c;如下图所示&#xff0c;则需要添加右键菜单&#xff1a; 2.添加右键菜单&#xff1a;选择“TortoiseSVN”&#xff0c;点击设置&#xff0c;如下图所示&a…

聊聊如何利用springcloud gateway实现简易版灰度路由

前言 前阵子时间和朋友聊天&#xff0c;他们有个sass微服务&#xff0c;因为之前拆分过细&#xff0c;导致服务不仅调用链路过长&#xff0c;而且浪费服务资源&#xff0c;他们后面做了服务合并的重构&#xff0c;并即将上线。他觉得上线不能直接把线上的租户都全切到重构版的…

【经验分享】Ubuntu如何设置swap交换

我的Linux小鸡内存只有512兆&#xff0c;经常爆内存&#xff0c;导致很多应用没有办法一直正常运行&#xff0c;可以通过设置swap来缓解一下&#xff0c;虽然和内存的速度无法媲美&#xff0c;但是能一定程度缓解一下问题 文章目录 1. 创建一个交换文件2. 设置正确的权限3. 设置…

再谈谈注解

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 注解&#xff0c;和反射…

浅谈 JVM GC 收集器--系列(一)

又到一年大促时刻&#xff0c;今天我们一起探讨下JVM垃圾回收的问题&#xff0c;写代码的时候想一想如何减少FullGC问题的出现&#xff0c;因为一旦出现频繁FullGC&#xff0c;短时间内没有太好的解决办法&#xff0c;很有可能重启后服务接着FullGC&#xff0c;导致服务可用率降…

【离散数学】——刷题题库(范式)

&#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java基础&#xff1a;Java基础_IT闫的博客-CSDN博客 &#x1f40b;c语言&#xff1a;c语言_IT闫的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…

Codeforces Round 910 (Div. 2) --- B-E 补题记录

B - Milena and Admirer Problem - B - Codeforces 题目大意&#xff1a; 现在给出一个无序序列&#xff0c;你可以使用任意次操作将这个无序序列修改为不递减序列&#xff0c;操作为你可以使用两个数a和b来替换ai&#xff0c;序列就变为了 ai-1&#xff0c; a&#xff0c;…

Flink Operator 使用指南 之 Flink Operator安装

介绍 Flink Kubernetes Operator 充当控制平面来管理 Apache Flink 应用程序的完整部署生命周期。尽管 Flink 的Native Kubernetes 集成已经允许用户在运行的 Kubernetes(k8s) 集群上直接部署 Flink 应用程序,但自定义资源和Operator Pattern 也已成为 Kubernetes 原生部署体…

# 学习 Prolog 和 离散逻辑的16个等价公式:一趟有趣的逻辑之旅

Prolog 的语法很奇怪,需要一些时间来适应,所以我花了点时间,想用Prolot来表示和验证离散逻辑的16组等价公式。 1. 双重否定律 (Double Negation Law) A ⇔A 首先&#xff0c;我们来看看双重否定律。在 Prolog 中&#xff0c;我们可以这样验证它&#xff1a; fun1(A,Z):-membe…

RK3588产测软件介绍

1. 简介 本公司研发的产测软件是用于在量产的过程中快速地甄别产品功能和器件的好坏&#xff0c;即重点 FCT&#xff08;Functional Test&#xff09;测试&#xff0c;进而提高生产效率和检测的准确性。 2. 产测软件介绍 QT开发的ARM平台产测图形化软件&#xff0c;一键开启傻…