英文:
Gzip compression not working in my project with Spring boot 1.5.10.RELEASE
问题
我正在使用 Spring Boot 1.5.10.RELEASE 版本。Gzip 压缩无法正常工作。
> http://localhost:9000 --> http://localhost:8080/api/..
AngularJS 和 REST API 使用不同的端口。启用 CrossOrigin 以接受来自 AngularJS 用户界面的请求。
使用嵌入式的 Tomcat 服务器部署 Spring Boot 应用程序。
未使用 http2 属性,即 server.http2.enabled=true
。
AngularJS 调用 REST API。以下是 $http 服务的代码:
$http({
method: method,
url: url,
params: params,
data: body,
headers: {
Authorization: token,
"Content-type": 'application/json'
}
});
REST API 响应大小约为 25MB,因此我希望压缩响应。
我已经在 application.properties 中添加了众所周知的属性来应用 Gzip 压缩。
Spring Boot 1.5.10 支持的属性
# 启用响应压缩
server.compression.enabled=true
# 应该压缩的逗号分隔的 MIME 类型列表
server.compression.mime-types=text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json
# 仅在响应大小至少为 1KB 时才压缩响应
server.compression.min-response-size=1024
我已经观察了网络标签,但在响应头中没有看到 Content-Encoding: gzip。
请求
请求 URL:http://localhost:9081/employee
请求方法:GET
状态码:200
远程地址:[::1]:9081
引用政策:no-referrer-when-downgrade
响应头
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://localhost:7000
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Type: application/json;charset=UTF-8
Date: Sun, 28 Jun 2020 18:15:17 GMT
Expires: 0
Pragma: no-cache
Set-Cookie: JSESSIONID=6E7C07874D0329E18A0C07E5E303F005; Path=/; HttpOnly
Transfer-Encoding: chunked
Vary: Origin
X-Application-Context: application
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
请求头
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Authorization: Bearer eyJhbGciOiJIUzINiJ9.eyJyb2xlIjiU0VDVE9SSEVBRCIsImxldmVsRG93biI6IkVENzA0MTI7TU04MzcyNDtKTDgzNTwO0RNNDAwNzE7Skc3MzA0NjtFQzM0NjEzO05OMTY5Nzk7QUs2MDYzNztTVDE4NTg4O0FTMjczNTE7Q0I4MTg3OTtWQTc4MTk5O0NNOTM3MDA7QVkyMzYzNztKUzcwMDY4O0NCMTc2NzE7TksyMTU2MDtMUzg4OTg0O0FQNTg3MDg7VFcyjk0NTtKSzI1Nzc3O01TNDk5MjE7SkI4OTcyOTtNSDAyMTI3O01CMTUwODk7SU0xMjgwODtNQzcxOTc2O1JSMjAzMDI7TFM1ODk4MiIsImxldmVsVXAiOm51bGwsImRlbGVnYXRlZCI6bnVsbCwic29lSWQiOiJTUjQ0MTg1I0.*************
Cache-Control: no-cache
Connection: keep-alive
Content-type: application/json
Host: localhost:9081
Origin: http://localhost:7000
Pragma: no-cache
Referer: http://localhost:7000/build/standalone.html
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36
我在响应头中没有看到以下期望的标头:
Content-Encoding: gzip
Vary: Accept-Encoding
在我的项目中,需要在客户端/服务器端进行任何更改吗?
---[编辑-1]-------------
我尝试了在单独的项目中使用 Gzip,它有效,但在我的项目中无效。
从浏览器调用 REST API 时的响应头如下:
Content-Encoding: gzip
Content-Type: application/json;charset=UTF-8
Date: Sun, 28 Jun 2020 18:12:29 GMT
Transfer-Encoding: chunked
Vary: Accept-Encoding
-----[编辑-2]-----Ziplet----
使用 ziplet 依赖项,我能够压缩响应,但我想使用 Spring Boot Gzip 压缩。
使用 Ziplet 时的响应头如下:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://localhost:7000
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Encoding: gzip
Content-Type: application/json;charset=UTF-8
Date: Mon, 06 Jul 2020 18:31:07 GMT
Expires: 0
Pragma: no-cache
Set-Cookie: JSESSIONID=8465D2E81A1A9CE146255B6C545FBE30; Path=/; HttpOnly
Transfer-Encoding: chunked
Vary: Accept-Encoding
Vary: Origin
X-Application-Context: application
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode
英文:
I am using Spring Boot 1.5.10.RELEASE version. Gzip compress not working.
> http://localhost:9000 --> http://localhost:8080/api/..
Angularjs & rest api on different Port. Enabled CrossOrigin to accept request from angularjs ui.
Using embedded tomcat server to deploy spring boot application.
Not using http2 property i.e. server.http2.enabled=true
Angualrjs calls rest api. Following is $http service
$http({
method: method,
url: url,
params: params,
data: body,
headers: {
Authorization: token,
"Content-type": 'application/json'
}
});
Rest api response size Approx 25 MB so I want to compress response.
I have added well known property in application.properties to apply gzip compression.
Spring boot 1.5.10 Supported properties
# Enable response compression
server.compression.enabled=true
# The comma-separated list of mime types that should be compressed
server.compression.mime-types=text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json
# Compress the response only if the response size is at least 1KB
server.compression.min-response-size=1024
I have observed network tab and no observed Content-Encoding: gzip in response header.
Request
Request URL: http://localhost:9081/employee
Request Method: GET
Status Code: 200
Remote Address: [::1]:9081
Referrer Policy: no-referrer-when-downgrade
Response Header
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://localhost:7000
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Type: application/json;charset=UTF-8
Date: Sun, 28 Jun 2020 18:15:17 GMT
Expires: 0
Pragma: no-cache
Set-Cookie: JSESSIONID=6E7C07874D0329E18A0C07E5E303F005; Path=/; HttpOnly
Transfer-Encoding: chunked
Vary: Origin
X-Application-Context: application
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Request Header
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Authorization: Bearer eyJhbGciOiJIUzINiJ9.eyJyb2xlIjiU0VDVE9SSEVBRCIsImxldmVsRG93biI6IkVENzA0MTI7TU04MzcyNDtKTDgzNTwO0RNNDAwNzE7Skc3MzA0NjtFQzM0NjEzO05OMTY5Nzk7QUs2MDYzNztTVDE4NTg4O0FTMjczNTE7Q0I4MTg3OTtWQTc4MTk5O0NNOTM3MDA7QVkyMzYzNztKUzcwMDY4O0NCMTc2NzE7TksyMTU2MDtMUzg4OTg0O0FQNTg3MDg7VFcyjk0NTtKSzI1Nzc3O01TNDk5MjE7SkI4OTcyOTtNSDAyMTI3O01CMTUwODk7SU0xMjgwODtNQzcxOTc2O1JSMjAzMDI7TFM1ODk4MiIsImxldmVsVXAiOm51bGwsImRlbGVnYXRlZCI6bnVsbCwic29lSWQiOiJTUjQ0MTg1I0.*************
Cache-Control: no-cache
Connection: keep-alive
Content-type: application/json
Host: localhost:9081
Origin: http://localhost:7000
Pragma: no-cache
Referer: http://localhost:7000/build/standalone.html
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36
I am not getting following expected headers in response header
Content-Encoding: gzip
Vary: Accept-Encoding
Any changes require at client /server side ?
---[Edit-1] -------------
Tried gzip in individual project which worked but not worked in my project.
Following is response header when invoke rest api from browser
Content-Encoding: gzip
Content-Type: application/json;charset=UTF-8
Date: Sun, 28 Jun 2020 18:12:29 GMT
Transfer-Encoding: chunked
Vary: Accept-Encoding
-----[Edit-2]-----Ziplet----
Using ziplet dependency I am able to compress response, but I want to use spring boot gzip compression.
Response header - when used Ziplet
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://localhost:7000
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Encoding: gzip
Content-Type: application/json;charset=UTF-8
Date: Mon, 06 Jul 2020 18:31:07 GMT
Expires: 0
Pragma: no-cache
Set-Cookie: JSESSIONID=8465D2E81A1A9CE146255B6C545FBE30; Path=/; HttpOnly
Transfer-Encoding: chunked
Vary: Accept-Encoding
Vary: Origin
X-Application-Context: application
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
When used ziplet - I can see
CompressingFilter : CompressingFilter has initialized
When using Spring boot gzip compression not observed anything where I can assume gzip compression enabled.
Any property to debug spring boot gzip compression with embeded tomcat ?
like logging.level.org.eclipse.jetty.server.handler.gzip=TRACE
How can i verify server.compression.enabled ?
Any changes require at client /server side in my project?
Thanks in advance.
答案1
得分: 3
根据你的问题,你正在使用 Spring Boot 1.5.10.RELEASE 版本。
在这个版本的框架中,类 TomcatEmbeddedServletContainerFactory
负责启动嵌入式的 Tomcat 容器。
该类和版本的源代码可以在这里找到:
在这个类中,你可以找到方法 customizeCompression
:
private void customizeCompression(Connector connector) {
ProtocolHandler handler = connector.getProtocolHandler();
if (handler instanceof AbstractHttp11Protocol) {
AbstractHttp11Protocol<?> protocol = (AbstractHttp11Protocol<?>) handler;
Compression compression = getCompression();
protocol.setCompression("on");
protocol.setCompressionMinSize(compression.getMinResponseSize());
configureCompressibleMimeTypes(protocol, compression);
if (getCompression().getExcludedUserAgents() != null) {
protocol.setNoCompressionUserAgents(
StringUtils.arrayToCommaDelimitedString(
getCompression().getExcludedUserAgents()));
}
}
}
尝试在这个方法上设置断点并调试你的应用程序,以查看压缩是否真正被启用。
如果没有启用压缩,很可能在你的项目中存在某种错误配置。
如果它起作用,这表明你的配置是正确的,问题可能是其他方面导致的。
如果是这种情况,在查看其他内容之前,可能适合尝试另一个服务器,比如 Jetty 或 Undertow,它们也支持这个压缩功能,然后看看是否一切正常。
例如,要配置 Undertow 而不是 Tomcat,你可以使用以下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
你还可以尝试以编程方式配置 Tomcat 压缩;参考 stackoverflow 问题中 matsev 的回答:
英文:
As your question, you are using Spring Boot 1.5.10.RELEASE.
For that version of the framework, the class TomcatEmbeddedServletContainerFactory
is responsible for starting the embedded Tomcat container.
The source code of that class and version can be found here:
In this class, you can find the method customizeCompression
:
private void customizeCompression(Connector connector) {
ProtocolHandler handler = connector.getProtocolHandler();
if (handler instanceof AbstractHttp11Protocol) {
AbstractHttp11Protocol<?> protocol = (AbstractHttp11Protocol<?>) handler;
Compression compression = getCompression();
protocol.setCompression("on");
protocol.setCompressionMinSize(compression.getMinResponseSize());
configureCompressibleMimeTypes(protocol, compression);
if (getCompression().getExcludedUserAgents() != null) {
protocol.setNoCompressionUserAgents(
StringUtils.arrayToCommaDelimitedString(
getCompression().getExcludedUserAgents()));
}
}
}
Try setting a breakpoint on this method and debug your application to see if compression is actually enabled.
If not, it is very likely that there is some kind of wrong configuration in your project.
If it works, it indicates that your configuration is correct and that the problem is different.
If this is the case, before looking at anything else, it might be appropriate to try another server, such as Jetty or Undertow, which also support this compression feature, and see if everything works correctly there.
For instance, to configure Undertow instead of Tomcat you can use the following:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
You can try to configure Tomcat compression programmatically as well; see matsev's answer in this stackoverflow question:
答案2
得分: -1
你必须在你的 Spring Boot 属性中启用 HTTP2 支持。
server.http2.enabled=true
然后尝试一下。
英文:
You have to enable http2 support in your spring boot properties
server.http2.enabled=true
And then try
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论