Nous utilisons Spring Boot/MVC avec Java-config basé sur des annotations pour une série de services RESTful
et nous souhaitons activer de manière sélective la compression de flux HTTP GZIP
sur certaines réponses de l'API.
Je sais que je peux le faire manuellement dans mon contrôleur et avec un byte[] @ResponseBody
. Cependant, nous préférerions nous appuyer sur l'infrastructure SpringMVC (filtres/etc.) et lui demander de faire automatiquement la conversion et la compression JSON (c'est-à-dire que la méthode retourne un POJO).
Comment puis-je activer la compression GZIP dans l'instance ResponseBody ou Tomcat intégrée et comment, de manière sélective, ne compresser que certaines réponses?
Merci!
PS: Nous n'avons actuellement aucune configuration basée sur XML.
Le reste de ces réponses est obsolète et/ou excessivement compliqué pour une chose qui devrait être simple. OMI (depuis combien de temps gzip existe-t-il maintenant? Plus longtemps que Java ...) D'après les documents:
Dans 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
Dans 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
Plus vieux que 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");
}
}
Si vous envisagez de déployer sur un Tomcat non incorporé, vous devrez l'activer dans server.xml http://Tomcat.Apache.org/Tomcat-9.0-doc/config/http.html#Standard_Implementation
Pour éviter tout cela, envisagez d'utiliser une configuration proxy/équilibreur de charge devant Tomcat avec nginx et/ou haproxy ou similaire, car elle gérera plus facilement et plus efficacement les actifs statiques et gzip MUCH par rapport à Java /. Modèle de threading de Tomcat.
Vous ne voulez pas jeter le chat dans le bain parce qu'il est occupé à compresser des choses au lieu de répondre aux demandes (ou plutôt à faire tourner des threads/à manger du CPU/du tas en attendant que la base de données IO se produise lors de l'exécution de votre La facture AWS, c’est la raison pour laquelle les versions traditionnelles de Java/Tomcat n’est peut-être pas une bonne idée de commencer en fonction de ce que vous faites, mais je m'éloigne du sujet ...)
C'est en gros la même solution que celle fournie par @ andy-wilkinson, mais à partir de Spring Boot 1.0, la méthode personnaliser (...) a un paramètre ConfigurableEmbeddedServletContainer .
Une autre chose à noter est que Tomcat ne compresse que les types de contenu text/html
, text/xml
et text/plain
par défaut. Vous trouverez ci-dessous un exemple prenant en charge la compression de 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);
}
}
);
}
};
}
Sur les versions récentes de application.yml
config:
---
spring:
profiles: dev
server:
compression:
enabled: true
mime-types: text/html,text/css,application/javascript,application/json
---
Spring Boot 1.4 Utilisez ceci pour Javascript HTML avec toutes les compressions.
server.compression.enabled: true
server.compression.mime-types: application/json,application/xml,text/html,text/xml,text/plain,text/css,application/javascript
Pour activer la compression GZIP, vous devez modifier la configuration de l'instance intégrée Tomcat. Pour ce faire, vous déclarez un bean EmbeddedServletContainerCustomizer
dans votre configuration Java, puis vous enregistrez une TomcatConnectorCustomizer
avec celui-ci.
Par exemple:
@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);
}
});
}
};
}
Reportez-vous à la documentation Tomcat pour plus de détails sur les différentes options de configuration de la compression disponibles.
Vous dites que vous souhaitez activer la compression de manière sélective. En fonction de vos critères de sélection, l’approche ci-dessus peut alors suffire. Il vous permet de contrôler la compression par l'agent utilisateur de la demande, la taille de la réponse et le type mime de la réponse.
Si cela ne répond pas à vos besoins, je pense que vous devrez effectuer la compression dans votre contrôleur et renvoyer une réponse octet [] avec un en-tête gzip content-encoding.
J'ai ajouté pour cela:
server.compression.enabled=true
server.compression.min-response-size=2048
server.compression.mime-types=application/json,application/xml,text/html,text/xml,text/plain
extrait de http://bisaga.com/blog/programming/web-compression-on-spring-boot-application/
L'activation de GZip dans Tomcat ne fonctionne pas dans mon projet de démarrage Spring. J'ai utilisé CompressingFilter trouvé ici .
@Bean
public Filter compressingFilter() {
CompressingFilter compressingFilter = new CompressingFilter();
return compressingFilter;
}
J'avais le même problème dans mon projet Spring Boot + Spring Data lors de l'appel à un @RepositoryRestResource
.
Le problème est le type MIME renvoyé. qui est application/hal+json
. L'ajouter à la propriété server.compression.mime-types
a résolu ce problème pour moi.
J'espère que cela aide quelqu'un d'autre!