it-swarm.com.de

Verwenden der GZIP-Komprimierung mit Spring Boot/MVC/JavaConfig mit RESTful

Wir verwenden Spring Boot/MVC mit annotationsbasierter Java-config für eine Reihe von RESTful-Diensten, und wir möchten für einige API-Antworten die HTTP GZIP-Stream-Komprimierung selektiv aktivieren.

Ich weiß, dass ich dies manuell in meinem Controller und einem byte[] @ResponseBody ausführen kann, wir würden uns jedoch lieber auf die SpringMVC-Infrastruktur (Filter/etc) verlassen und diese JSON-Konvertierung und -Komprimierung automatisch durchführen lassen (dh die Methode gibt ein POJO zurück).

Wie kann ich die GZIP-Komprimierung in der ResponseBody- oder Embedded-Tomcat-Instanz aktivieren und auf eine Weise selektiv komprimieren, dass nur einige Antworten gezählt werden?

Vielen Dank!

PS .: Derzeit haben wir keine XML-basierte Konfiguration.

79
user3182614

Der Rest dieser Antworten ist veraltet und/oder übertrieben kompliziert für etwas, das einfach IMO sein sollte (wie lange gibt es gzip jetzt? Länger als Java ...) Aus den Dokumenten:

In application.properties 1.3+

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

In 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

Älter als 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");
  }
}

Beachten Sie auch, dass dies NUR funktioniert, wenn Sie Embedded Tomcat ausführen:

Wenn Sie die Bereitstellung auf einem nicht eingebetteten Tomcat planen, müssen Sie es in server.xml http://Tomcat.Apache.org/Tomcat-9.0-doc/config/http.html#Standard_Implementation aktivieren.

IRL-Produktionshinweis:

Um all dies zu vermeiden, sollten Sie ein Proxy/Load Balancer-Setup vor Tomcat mit nginx und/oder haproxy oder ähnlichem verwenden, da statische Assets und gzip VIEL effizienter und einfacher als mit Java/Tomcat's Threading-Modell.

Sie wollen keine Katze ins Bad werfen, weil sie damit beschäftigt ist, Sachen zu komprimieren, anstatt Anfragen zu bearbeiten (oder eher Threads hochzudrehen/CPU/Heap zu fressen, die darauf warten, dass die Datenbank IO beim Hochfahren der Datenbank auftritt AWS Rechnung, weshalb traditionelles Java/Tomcat vielleicht keine gute Idee ist, je nachdem, was Sie tun, aber ich schweife ab ...)

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

163
John Culviner

Dies ist im Grunde die gleiche Lösung wie @ andy-wilkinson, aber ab Spring Boot 1.0 verfügt die custom (...) - Methode über einen ConfigurableEmbeddedServletContainer -Parameter. 

Erwähnenswert ist auch, dass Tomcat standardmäßig nur die Inhaltstypen text/html, text/xml und text/plain komprimiert. Das folgende Beispiel unterstützt die Komprimierung von 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);
                        }
                    }
            );
        }
    };
}
12
matsev

Bei den letzten Versionen in application.yml config:

---

spring:
  profiles: dev

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

---
11

Spring Boot 1.4 Verwenden Sie diese Option für Javascript HTML Json für alle Komprimierungen.

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

Um die GZIP-Komprimierung zu aktivieren, müssen Sie die Konfiguration der eingebetteten Tomcat-Instanz ändern. Dazu deklarieren Sie eine EmbeddedServletContainerCustomizer-Bean in Ihrer Java-Konfiguration und registrieren dann eine TomcatConnectorCustomizer damit.

Zum Beispiel:

@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);
                }
            });
        }
    };
}

Weitere Informationen zu den verschiedenen verfügbaren Konfigurationsoptionen für die Komprimierung finden Sie in der Tomcat-Dokumentation .

Sie sagen, dass Sie die Komprimierung selektiv aktivieren möchten. Abhängig von Ihren Auswahlkriterien kann der obige Ansatz ausreichend sein. Damit können Sie die Komprimierung durch den Benutzeragenten der Anforderung, die Größe der Antwort und den Mime-Typ der Antwort steuern.

Wenn dies nicht Ihren Anforderungen entspricht, müssen Sie die Komprimierung in Ihrem Controller durchführen und eine Byte [] - Antwort mit einem gzip-Inhaltscodierungsheader zurückgeben.

4
Andy Wilkinson

Ich habe dazu hinzugefügt: 

Server-Komprimierung

server.compression.enabled=true
server.compression.min-response-size=2048
server.compression.mime-types=application/json,application/xml,text/html,text/xml,text/plain

entnommen aus http://bisaga.com/blog/programming/web-compression-on-spring-boot-application/

4

Die Aktivierung von GZip in Tomcat hat in meinem Spring Boot-Projekt nicht funktioniert. Ich habe CompressingFilter found hier verwendet.

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

Ich hatte das gleiche Problem in meinem Spring Boot + Spring Data-Projekt, als ich einen @RepositoryRestResource aufrief.

Das Problem ist der zurückgegebene MIME-Typ. Welches ist application/hal+json. Das Hinzufügen zur server.compression.mime-types-Eigenschaft löste dieses Problem für mich.

Hoffe das hilft jemand anderem!

0
Serginho