Gzip压缩在我的项目中不起作用,使用的是Spring Boot 1.5.10.RELEASE版本。

huangapple go评论75阅读模式
英文:

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 容器。

该类和版本的源代码可以在这里找到:

https://github.com/spring-projects/spring-boot/blob/v1.5.10.RELEASE/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java

在这个类中,你可以找到方法 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 的回答:

https://stackoverflow.com/questions/21410317/using-gzip-compression-with-spring-boot-mvc-javaconfig-with-restful/28216983

英文:

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:

https://github.com/spring-projects/spring-boot/blob/v1.5.10.RELEASE/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java

In this class, you can find the method customizeCompression:

private void customizeCompression(Connector connector) {
  ProtocolHandler handler = connector.getProtocolHandler();
  if (handler instanceof AbstractHttp11Protocol) {
    AbstractHttp11Protocol&lt;?&gt; protocol = (AbstractHttp11Protocol&lt;?&gt;) handler;
    Compression compression = getCompression();
    protocol.setCompression(&quot;on&quot;);
    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:

&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
    &lt;exclusions&gt;
        &lt;exclusion&gt;
            &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
            &lt;artifactId&gt;spring-boot-starter-tomcat&lt;/artifactId&gt;
        &lt;/exclusion&gt;
    &lt;/exclusions&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-undertow&lt;/artifactId&gt;
&lt;/dependency&gt;

You can try to configure Tomcat compression programmatically as well; see matsev's answer in this stackoverflow question:

https://stackoverflow.com/questions/21410317/using-gzip-compression-with-spring-boot-mvc-javaconfig-with-restful/28216983

答案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

huangapple
  • 本文由 发表于 2020年6月29日 02:46:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/62626807.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定