RESTfulでSpring Boot / MVC / JavaConfigでGZIP圧縮を使用する


95

私たちは、一連のRESTfulサービスに対してアノテーションベースのjava-configでSpring Boot / MVCを使用しHTTP GZIP、一部のAPI応答でストリーム圧縮を選択的に有効にしたいと考えています。

私は自分のコントローラーとでこれを手動で実行できることを知っていますがbyte[] @ResponseBody、SpringMVCインフラストラクチャ(フィルターなど)に依存して、JSON変換と圧縮を自動的に実行する(つまり、メソッドがPOJOを返す)ことを望みます。

ResponseBodyまたは埋め込みTomcatインスタンスでGZIP圧縮を有効にするにはどうすればよいですか。また、一部の応答のみを選択的に圧縮できるようにするにはどうすればよいですか。

ありがとう!

PS .:現在、XMLベースの構成はありません。


GzipFilterをチェックしてください
Approxiblue 2014

2
何をしているのかわからない場合は、HTTPSでHTTP圧縮を使用しないでください
Neil McGuigan

回答:


188

これらの残りの回答は古くなっているか、単純なIMOである必要があるために複雑になっています(gzipは現在どのくらいの期間使用されていますか?Javaよりも長い...)ドキュメントから:

application.properties 1.3以降

# 🗜️🗜️🗜️
server.compression.enabled=true
# opt in to content types
server.compression.mime-types=application/json,application/xml,text/html,text/xml,text/plain,application/javascript,text/css
# not worth the CPU cycles at some point, probably
server.compression.min-response-size=10240 

application.properties 1.2.2-<1.3

server.tomcat.compression=on
server.tomcat.compressableMimeTypes=application/json,application/xml,text/html,text/xml,text/plain,application/javascript,text/css

1.2.2より前:

@Component
public class TomcatCustomizer implements TomcatConnectorCustomizer {

  @Override
  public void customize(Connector connector) {
    connector.setProperty("compression", "on");
    // Add json and xml mime types, as they're not in the mimetype list by default
    connector.setProperty("compressableMimeType", "text/html,text/xml,text/plain,application/json,application/xml");
  }
}

また、埋め込まれたTomcatを実行している場合にのみ機能することにも注意してください。

埋め込みでないTomcatにデプロイする場合は、server.xmlで有効にする必要がありますhttp://tomcat.apache.org/tomcat-9.0-doc/config/http.html#Standard_Implementation

IRLプロダクションノート:

また、これらすべてを回避するために、nginxhaproxyなどを使用してTomcatの前にプロキシ/ロードバランサ設定を使用することを検討してください。静的アセットとgzipは、Java / Tomcatのスレッドモデルよりも効率的かつ簡単に処理されます。

それはリクエストを処理する代わりにものを圧縮するのに忙しいので「浴室で猫を投げたくありません」(または可能性が高いです)伝統的なJava / Tomcatが、あなたがやっていることによっては最初から始めた方がいいのではないかもしれませんが、私は余談です...)

refs:https : //docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/html/howto.html#how-to-enable-http-response-compression

https://github.com/spring-projects/spring-boot/issues/2031


Spring BootはTomcatConnectorCustomizerアプリケーションコンテキストでインスタンスを検索しないため、1.2.2より古いバージョンのアプローチは機能しません。プログラムに登録する必要がありますTomcatEmbeddedServletContainerFactory
アンディウィルキンソン

ヘッドアップをありがとう。静的/動的/ tomcat / vsブートがまだ問題であるように思われたので、私はこれをあきらめました。これは本来あるべきことよりもはるかに難しい... NginxリバースプロキシFTW!
John Culviner、2015

3
SpringBootでは、新しいプロパティはserver.compression.enabled = trueおよびserver.compression.mime-types = XXX、YYYgithub.com/spring
projects/

2
スプリングブートの場合、複数のRESTコントローラーがあり、すべてJSON応答を返します。一部のコントローラーに選択的にzipを適用できますか?

3
また、圧縮の最小応答サイズ(例:10KB)についても言及する必要があります。そうしないと、サーバーがすべての(例:0.5KB)リクエストを圧縮するためのオーバーヘッドになります。server.compression.min-response-size=10240
UsamaAmjad


12

これは基本的には提供されている@ andy-wilkinsonと同じソリューションですが、Spring Boot 1.0以降では、customize(...)メソッドにConfigurableEmbeddedServletContainerパラメーターがあります。

言及する価値があるもう一つは、Tomcatは唯一のコンテンツタイプを圧縮していることであるtext/htmltext/xmltext/plainデフォルトで。以下は、application/json同様に圧縮をサポートする例です。

@Bean
public EmbeddedServletContainerCustomizer servletContainerCustomizer() {
    return new EmbeddedServletContainerCustomizer() {
        @Override
        public void customize(ConfigurableEmbeddedServletContainer servletContainer) {
            ((TomcatEmbeddedServletContainerFactory) servletContainer).addConnectorCustomizers(
                    new TomcatConnectorCustomizer() {
                        @Override
                        public void customize(Connector connector) {
                            AbstractHttp11Protocol httpProtocol = (AbstractHttp11Protocol) connector.getProtocolHandler();
                            httpProtocol.setCompression("on");
                            httpProtocol.setCompressionMinSize(256);
                            String mimeTypes = httpProtocol.getCompressableMimeTypes();
                            String mimeTypesWithJson = mimeTypes + "," + MediaType.APPLICATION_JSON_VALUE;
                            httpProtocol.setCompressableMimeTypes(mimeTypesWithJson);
                        }
                    }
            );
        }
    };
}

これをJava構成に追加してみましたが、圧縮がまったく機能していないようです。埋め込みコンテナーとしてTomcatでSpring Bootを使用していて、この構成以外に設定する必要がある追加のものがあったかどうか疑問に思いましたか?
マイケルコクソン2014

2
Accept-Encoding: gzip,deflatecurlを使用している場合は、ヘッダーを指定して確認してください:curl -i -H 'Accept-Encoding: gzip,deflate' http://url.to.your.server
matsev

9

Spring Boot 1.4 Javascript HTML Jsonすべての圧縮にこれを使用します。

server.compression.enabled: true
server.compression.mime-types: application/json,application/xml,text/html,text/xml,text/plain,text/css,application/javascript

この圧縮をどのように確認しますか?
Bhargav 2017

@Bhargav API応答の応答ヘッダーを確認します。ヘッダーが含まれている必要がありますContent-Encoding::gzip
Sumit Jha


6

TomcatのEnabeling GZipがSpring Boot Projectで機能しません。ここにあるCompressingFilterを使用しまし

@Bean
public Filter compressingFilter() {
    CompressingFilter compressingFilter = new CompressingFilter();
    return compressingFilter;
}

@ user1127860 tnxこれは機能しますが、とにかくこのフィルターをさらに構成しますか?私はスプリングブートを使用しており、マニュアルのweb.xmlにあるようにinit paramsを追加できないようです
Spring

5

GZIP圧縮を有効にするには、組み込みのTomcatインスタンスの構成を変更する必要があります。そのためにEmbeddedServletContainerCustomizerは、Java構成でBean を宣言し、それをに登録TomcatConnectorCustomizerします。

例えば:

@Bean
public EmbeddedServletContainerCustomizer servletContainerCustomizer() {
    return new EmbeddedServletContainerCustomizer() {
        @Override
        public void customize(ConfigurableEmbeddedServletContainerFactory factory) {
            ((TomcatEmbeddedServletContainerFactory) factory).addConnectorCustomizers(new TomcatConnectorCustomizer() {
                @Override
                public void customize(Connector connector) {
                    AbstractHttp11Protocol httpProtocol = (AbstractHttp11Protocol) connector.getProtocolHandler();
                    httpProtocol.setCompression("on");
                    httpProtocol.setCompressionMinSize(64);
                }
            });
        }
    };
}

使用可能なさまざまな圧縮構成オプションの詳細については、Tomcatのドキュメントを参照してください

圧縮を選択的に有効にするとします。選択基準によっては、上記のアプローチで十分な場合があります。リクエストのユーザーエージェント、レスポンスのサイズ、レスポンスのMIMEタイプによって圧縮を制御できます。

これがニーズを満たさない場合は、コントローラーで圧縮を実行し、gzip content-encodingヘッダーを含むbyte []応答を返す必要があると思います。


1
application.propertiesに設定を置くオプションに対するあなたの答えの違いは何ですか?server.compression.enabled = true server.compression.mime-types = application / json、application / xml、text / html、text / xml、text / plain、application / javascript、text / css
lukass77

この回答は、プロパティベースの圧縮構成が利用可能になる前に書かれました。それらは同等ですが、プロパティベースのアプローチの方が簡単なので、それを使用することをお勧めします。
アンディウィルキンソン

私の場合、Tomcatがhttpsを取得し、Tomcatへのリクエストをhttpとして転送するロードバランサーの背後にあることを共有したいだけです。application.propertiesソリューションを使用すると、応答がgzipではなく、コネクタでプログラムによる構成ソリューションを使用すると、 httpsリクエストLBを使用したgzip応答
lukass77

私がapplication.propertiesソリューションを使用し、8081および8082ポートにさらに2つのコネクタを定義する場合の別の質問..すべてのコネクタまたは8080コネクタのみに圧縮が適用されますか?
lukass77 2018

私はこれを確認し、より多くのコネクタを開いた場合でも、比較はポート8080にのみ適用されます..、これでスプリングブートのためにバグを開く必要があると思いますか? application.propertiesではない
lukass77

0

を呼び出すときに、Spring Boot + Spring Dataプロジェクトで同じ問題が発生しました@RepositoryRestResource

問題は、返されるMIMEタイプです。それはapplication/hal+jsonです。server.compression.mime-typesプロパティに追加すると、この問題は解決しました。

これが他の誰かに役立つことを願っています!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.