当前位置: 首页 > news >正文

SpringBoot中 Gzip 压缩的两种开启方式:GeoJSON 瘦身实战

目录

前言

一、GZIP压缩知识简介

1、什么是Gzip

2、Gzip特点

3、Gzip在GIS方面的应用

二、SpringBoot中开启Gzip的方式

1、在SpringBoot中开启Gzip的知识简介

2、SpringBoot中GeoJSON的实例

三、全局开启Gzip实现

1、实现原理

2、实现效果

四、局部约定配置

1、实现原理

2、具体代码实现

五、总结


前言

        在当今数字化时代,随着互联网应用的飞速发展,数据传输的效率和性能成为了至关重要的问题。GeoJSON 是一种基于 JSON 格式的地理空间数据交换格式,它广泛应用于地理信息系统(GIS)领域,用于描述地理空间数据的几何形状、属性等信息。GeoJSON 数据通常包含大量的地理坐标点、几何形状等信息,数据量往往较大。在 Web 地理信息系统应用中,如地图展示、地理数据可视化等场景,GeoJSON 数据的传输效率直接关系到地图加载的速度和用户体验。因此,对 GeoJSON 数据进行有效的压缩,以减少数据传输的体积,显得尤为重要。对于基于SpringBoot 框架构建的 WebGIS 应用来说,如何高效地传输数据、减少网络带宽的占用,是提升用户体验和系统性能的关键所在。而 Gzip 压缩技术,作为一种被广泛采用的解决方案,无疑为这一问题的解决提供了强大的助力。

        以 GeoJSON 数据为例,通过在 SpringBoot 应用中开启 Gzip 压缩,对 GeoJSON 数据进行瘦身,不仅可以显著减少数据传输的体积,提高地图加载的速度,还可以提升用户的交互体验。在实际的 Web 地理信息系统开发中,这种优化手段是非常实用和有效的。通过对 GeoJSON 数据的压缩处理,我们可以更好地满足用户对于地图快速加载和流畅交互的需求,同时也为整个应用的性能优化提供了有力的支持。

        在接下来的内容中,我们将详细介绍在 SpringBoot 中开启 Gzip 压缩的两种方式的具体实现步骤,并通过实际的 GeoJSON 数据压缩案例,展示这两种方式的应用效果和优缺点。希望通过本文的介绍,能够帮助读者更好地理解和掌握在 SpringBoot 应用中使用 Gzip 压缩技术的方法,从而提升自己开发的 WebGIS 应用的性能和用户体验。

一、GZIP压缩知识简介

        GZIP 是一种数据压缩格式,只能用于压缩单个文件。它可用于网络文件传输时的压缩,例如 nginx 中的 ngx_http_gzip_module,启用压缩功能后可以节约带宽;也可用于本地文件存储时的压缩。本节将重点对Gzip进行一个简单的介绍,让大家对Gzip的相关知识有一个简单的了解。

1、什么是Gzip

        Gzip 的压缩算法基于 LZ77 算法Huffman 编码 的结合。具体过程如下:

        LZ77 算法:LZ77 算法通过查找和替换重复的字节序列来压缩数据。它维护一个滑动窗口,在窗口内查找匹配的字符串,然后使用指针来替代这些重复的字符串。例如,对于字符串 "http://jiurl.yeah.nethttp://jiurl.nease.net",LZ77 算法会将其压缩为 "http://jiurl.yeah.net(22,13)nease(23,4)",其中 (22,13) 表示距离当前位置 22 个字符处的 13 个字符与当前位置的字符相同。

        Huffman 编码:Huffman 编码是一种基于字符频率的编码方法。它为出现频率高的字符分配较短的编码,为出现频率低的字符分配较长的编码,从而达到压缩的目的。在 Gzip 中,LZ77 算法的输出结果会进一步通过 Huffman 编码进行压缩。

        Gzip 文件结构:Gzip 文件包含文件头、压缩数据块和文件尾。文件头存储文件的元数据,如压缩方法、时间戳等;压缩数据块是使用 DEFLATE 算法压缩后的数据;文件尾存储校验和(CRC32)和原始文件大小,以确保文件的完整性

2、Gzip特点

        无损压缩:Gzip 是一种无损压缩算法,数据在解压缩后可以完全还原,没有任何损失。

        高效的压缩率:对于文本文件(如 HTML、JSON、XML),Gzip 的压缩率通常在 50%-90% 之间。它通过查找重复的字符串并用较短的指针替代,以及根据字符频率进行编码,从而实现高效压缩。

        广泛支持:Gzip 被几乎所有现代浏览器、服务器和编程语言支持。在 HTTP 传输中,服务器可以根据浏览器的请求头(如 Accept-Encoding: gzip)来判断是否使用 Gzip 压缩响应内容。

        压缩和解压速度较快:Gzip 的压缩和解压速度相对较快,尤其是解压过程,因为解压时只需根据指针和编码还原数据,计算量相对较小。

        适用于特定文件类型:Gzip 对文本文件的压缩效果较好,但对于已经压缩过的文件(如图片、音乐、视频)效果不明显,甚至可能导致文件变大

3、Gzip在GIS方面的应用

        地理数据传输:在 GIS 应用中,地理数据(如 GeoJSON 文件)通常包含大量的坐标点和几何形状信息,数据量较大。使用 Gzip 压缩可以显著减少数据传输的体积,加快地图加载速度,提升用户体验。

        服务器端优化:在服务器端,可以配置 Web 服务器(如 Nginx)开启 Gzip 压缩功能。当客户端请求地理数据时,服务器会自动对响应内容进行压缩,减少网络带宽的占用。

        前端性能优化:在前端开发中,可以通过工具(如 Webpack 的 Compression-webpack-plugin 插件)在构建过程中对地理数据文件进行 Gzip 压缩,然后在服务器上直接提供压缩后的文件,减少服务器的实时压缩负载。

        数据存储优化:对于存储在服务器上的地理数据文件,使用 Gzip 压缩可以节省存储空间。在需要读取数据时,再进行解压处理。

        总之,Gzip 压缩技术在 GIS 领域的应用,不仅可以提高数据传输效率,还可以优化服务器性能和存储空间,是提升 GIS 应用性能的重要手段之一。

二、SpringBoot中开启Gzip的方式

        SpringBoot 是一个非常流行的 Java 基于 Spring 框架的快速开发框架,它极大地简化了 Spring 应用的开发过程。在 SpringBoot 应用中,通过合理的配置和编程,可以很方便地集成 Gzip 压缩功能,从而实现对响应数据的自动压缩。这不仅可以提高数据传输的效率,还可以减轻服务器的负载,提升整个应用的性能。本节将重点介绍在SpringBoot中关于Gzip的相关知识以及在SpringBoot中GeoJSON的一些实践案例。      

1、在SpringBoot中开启Gzip的知识简介

        在 SpringBoot 中,开启 Gzip 压缩主要有两种方式:一种是通过配置文件进行全局配置,另一种是通过编程的方式在特定的控制器或方法上进行局部配置。这两种方式各有优缺点,适用于不同的应用场景。

        全局配置方式 :通过在 SpringBoot 的配置文件(如 application.yml 或 application.properties)中添加相关的 Gzip 压缩配置,可以实现对整个应用的 HTTP 响应进行统一的压缩处理。这种方式简单方便,适用于大多数需要压缩的场景,但缺乏对特定数据类型的针对性处理。

        局部配置方式 :通过在控制器或方法上添加自定义的注解或逻辑,可以实现对特定数据类型的压缩处理。这种方式更加灵活,可以根据不同的数据类型和业务需求,定制不同的压缩策略,但相对来说实现起来较为复杂,需要更多的编程工作。

        这里首先简单介绍了两种在SpringBoot中开启Gzip压缩的方式,为下文全面讲解这两种方式做准备,先让大家了解相关知识。

2、SpringBoot中GeoJSON的实例

        GeoJSON在WebGIS中的用处很多,很多矢量数据的边界,范围点等数据,我们都是直接以GeoJSON的格式返回给前端,并直接进行展示的。比如之前很多的行政区划展示,省市县等不同的行政区划范围展示等,我们的实现过程都是在后台的Controller层中返回一个包含GeoJSON的对象,方法如下:

package com.yelang.project.meteorology.domain;
import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Data
@ToString(callSuper=true)//callSuper=true表示输出父类属性
@EqualsAndHashCode(callSuper=false)
public class AreaWeatherVO extends WeatherNow implements Serializable{private static final long serialVersionUID = -7559774548761847068L;@TableField(exist = false,value= "province_code")private String provinceCode;@TableField(exist = false,value= "province_name")private String provinceName;@TableField(exist = false,value= "city_code")private String cityCode;@TableField(exist = false,value= "city_name")private String cityName;@TableField(exist = false,value= "area_name")private String areaName;@TableField(exist = false)private String geomJson;private String lat;private String lon;
}

        上面是一个视图对象的具体代码,在Controller的方法中我们调用如下:

@RequiresPermissions("met:province:weather:list")
@GetMapping("/list/{pcode}")
@ResponseBody
public AjaxResult ewsnProvinceList(@PathVariable("pcode") String pcode){String day = "2025-08-17";List<AreaWeatherVO> dataList = weatherNowService.getWeatherByProvinceAndday(pcode,day);return AjaxResult.success().put("data", dataList);}

        经过以上的代码输出接口中就包含GeoJOSN数据,如下图所示:

        其具体的geoJSON值如下图:

        在网络窗口中可以看到整个接口返回的数据大小大约为5MB,如果遇到更大范围的行政区划,返回的数据肯定会大,比如西藏的行政区划大约有14MB,如图所示:

        那么如何通过开启Gzip来减少这些数据的输出呢?下面两个部分来重点讲解。

三、全局开启Gzip实现

        本节将详细介绍如何在SpringBoot中开启Gzip压缩的配置。

1、实现原理

        在 application.ymlapplication.properties 中添加以下配置:

        示例:application.yml

server:compression:enabled: truemime-types: application/jsonmin-response-size: 1KB  # 小于1KB的响应不压缩

        或者application.properties中:

server.compression.enabled=true
server.compression.mime-types=application/json
server.compression.min-response-size=1024

        请注意:该配置会对所有返回 application/json 的接口启用 GZIP 压缩。

2、实现效果

        在我们的工程中配置文件是以yml的形式配置的,按照上面的步骤进行设置后,重新启动应用程序后来看一下同样的接口,其返回的数据量大小是多少:

        通过以上图片可以直观的看到,开启全局压缩后,我们的接口返回大小,从14.4M下降了5MB,几乎是原来的1/3,这个压缩比例还是可以的。

四、局部约定配置

上面的这种实现方式全局的开启,也就是所有的接口都会开启,虽然可以设置mime-types来进行一定的过滤,但是依然会有很大的覆盖面。如果只想对某个接口生效或者指定一些接口生效又应该怎么实现呢?本节来讲讲针对这种情况的实现。

1、实现原理

        基于局部约定配置的方式的实现原理其实是通过自定义 Filter 来精确控制哪些接口启用压缩,因此通过过滤器就可以将我们需要设定的请求路径进行针对性过滤,从而开启针对这些接口的Gzip过滤压缩。下面我们来看看在SpringBoot中如何实现呢?

2、具体代码实现

首先在SpringBoot中直接创建一个过滤器Filter,关键代码如下:

package com.yelang.framework.interceptor.gzip;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.zip.GZIPOutputStream;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
@Component
public class SelectiveGzipFilter implements Filter {private final AntPathMatcher pathMatcher = new AntPathMatcher();private final List<String> gzipPatterns = Arrays.asList("/eq/province/geojson/**","/eq/province/detourcoefficient/list/**","/eq/info/home/earthinfo","/eq/province/abbreviations/list");@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {HttpServletRequest req = (HttpServletRequest) request;String requestUri = req.getRequestURI();String contextPath = req.getContextPath();boolean match = gzipPatterns.stream().anyMatch(pattern -> pathMatcher.match(pattern, requestUri));if (match) {System.out.println("成功匹配");// 启用 GZIP 压缩逻辑(同上)HttpServletResponse res = (HttpServletResponse) response;res.setHeader("Content-Encoding", "gzip");res.setHeader("Content-Type", "application/json");GZIPResponseWrapper gzipResponse = new GZIPResponseWrapper(res);chain.doFilter(request, gzipResponse);gzipResponse.finish();} else {System.out.println("未匹配上...");chain.doFilter(request, response);}}static class GZIPResponseWrapper extends HttpServletResponseWrapper {private final GZIPOutputStream gzipOutputStream;public GZIPResponseWrapper(HttpServletResponse response) throws IOException {super(response);gzipOutputStream = new GZIPOutputStream(response.getOutputStream());}@Overridepublic ServletOutputStream getOutputStream() {return new ServletOutputStream() {@Overridepublic void write(int b) throws IOException {gzipOutputStream.write(b);}@Overridepublic boolean isReady() {return true;}@Overridepublic void setWriteListener(WriteListener writeListener) {throw new UnsupportedOperationException();}};}public void finish() throws IOException {gzipOutputStream.finish();}}
}

        这里演示了如何设置多个目标URL地址的配置方式,使用AntPathMatcher 来进行匹配实现。需要注意的是,这里我们没有区分请求的头地址,以若依为例,可能会在匹配时无法正确对应,导致无法正常的开启Gzip压缩,因此为了保证正确的启用,我们在进行地址匹配时,需要自动过滤项目的服务名称,详细代码如下:

String contextPath = req.getContextPath();
// 去掉 context-path 部分,只匹配相对路径
String relativePath = requestUri.substring(contextPath.length());
System.out.println("relativePath==>" + relativePath);
/*boolean match = gzipPatterns.stream().anyMatch(pattern -> pathMatcher.match(pattern, requestUri));*/
boolean match = gzipPatterns.stream().anyMatch(pattern -> pathMatcher.match(pattern, relativePath));

        其实这里的contenxPath对应的就是配置文件中定义的参数:

# 开发环境配置
server:# 服务器的HTTP端口,默认为80port: 8080servlet:# 应用的访问路径context-path: /earthqadmin

        GeoJSON 数据通常体积较大,压缩后可显著减少传输时间。以下是实战建议:      

项目建议值说明
压缩类型GZIP浏览器原生支持
最小压缩阈值1KB 或更小GeoJSON 一般远大于此值
MIME 类型application/json保持标准兼容
实测效果原始 15MB → 压缩后 300KB压缩率可达 90%+

        只有加上以上代码后才能实现正确匹配,在访问地址被请求是输出如下信息:

五、总结

        以上就是本文的主要内容,我们将详细介绍在 SpringBoot 中开启 Gzip 压缩的两种方式的具体实现步骤,并通过实际的 GeoJSON 数据压缩案例,展示这两种方式的应用效果和优缺点。希望通过本文的介绍,能够帮助读者更好地理解和掌握在 SpringBoot 应用中使用 Gzip 压缩技术的方法,从而提升自己开发的 WebGIS 应用的性能和用户体验。博文首先简单介绍了Gzip的相关知识,然后介绍了在SpringBoot中开启Gzip的方式,最后以代码加案例的形式详细的介绍全局开启Gzip和局部开启Gzip的两种不同模式实现原理及具体代码实现。行文仓促,定有不足之处,欢迎各位朋友在评论区批评指正,不胜感激。

http://www.dtcms.com/a/366707.html

相关文章:

  • k8s基础(未完待续)
  • 拜占庭攻击与投毒攻击
  • Linux编写shell脚本,输入多个原文件名和新文件名,一次对多个文件重命名
  • 2025亚马逊卖家防恶搞指南:揪出恶意套路,3招守住店铺安全
  • Gmail 数据泄露安全警报以及启示
  • 23种设计模式——抽象工厂模式(Abstract Factory Pattern)详解
  • C++开发中的常用设计模式:深入解析与应用场景
  • Nginx 实战系列(一)—— Web 核心概念、HTTP/HTTPS协议 与 Nginx 安装
  • 移远EC200A OpenCPU笔记
  • 【bash】命令查看当前目录下文件个数
  • STM32G4 速度环开环,电流环闭环 IF模式建模
  • 发票、收据合并 PDF 小程序,报销上传 3 秒搞定
  • Beautiful.ai:AI辅助PPT工具高效搞定排版,告别熬夜做汇报烦恼
  • Redis的过期策略和Redis 内存淘汰策略
  • Uni-App + Vue onLoad与onLaunch执行顺序问题完整解决方案 – 3种实用方法详解
  • 【系统架构设计(13)】项目管理上:盈亏平衡分析与进度管理
  • android seekbar显示刻度
  • 深入内核交互:用 strace 看清 Android 每一个系统调用
  • Android实战进阶 - 富文本
  • iPhone17再爆猛料?苹果2025秋季发布会亮点抢先看
  • 北斗导航 | Android Studio开发NMEA0183上位机的技术方案
  • 邮件如何防泄密?这10个电子邮件安全解决方案真的好用,快收藏
  • 02-Media-4-mp4muxer.py 录制视频并保存为MP4文件的示例
  • 2025年数学建模国赛C题第二版本超详细解题思路
  • Android adb shell命令分析应用内存占用
  • 公司机密视频泄露频发?如何让机密视频只在公司内部播放
  • 硬件开发1-51单片机3-串口
  • 【Bluedroid】 A2DP Source 音频会话终止流程解析(btif_a2dp_source_end_session)
  • MySQL数据库和SQL语言
  • ReactPHP、Swoole、Webman、FrankenPHP 深度对比 找到最适合你的 PHP 异步方案