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.
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");
}
}
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.
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 ...)
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);
}
}
);
}
};
}
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
---
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
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.
Ich habe dazu hinzugefügt:
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/
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;
}
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!