Utilisation de la compression GZIP avec Spring Boot / MVC / JavaConfig avec RESTful


Nous utilisons Spring Boot/MVC avec java-config basé sur les annotations pour les séries de services RESTful et nous voulons activer sélectivement la compression de flux HTTP GZIP sur certaines réponses API.

Je sais que je peux le faire manuellement dans mon contrôleur et un byte[] @ResponseBody, mais nous préférerions compter sur l'infrastructure SpringMVC (filtres/etc) et lui faire effectuer automatiquement la conversion et la compression JSON (c'est-à-dire que la méthode renvoie un POJO).

Comment puis-je activer la compression GZIP dans le ResponseBody ou embedded Instance Tomcat, et d'une certaine manière, nous pouvons compresser sélectivement seulement certaines réponses?

Merci!

PS.: Nous n'avons actuellement aucune configuration basée sur XML.

Author: guisantogui, 2014-01-28

8 answers

Le reste de ces réponses est obsolète et / ou trop compliqué pour quelque chose qui devrait être simple IMO (depuis combien de temps gzip existe-t-il pour l'instant? plus long que Java...) À partir des documents:

En application.propriétés 1.3+

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

En application.propriétés 1.2.2 -

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

Notez également que cela ne fonctionnera que si vous exécutez embedded tomcat:

Si vous prévoyez de déployer sur un tomcat non intégré, vous devrez activer le serveur informatique.xml http://tomcat.apache.org/tomcat-9.0-doc/config/http.html#Standard_Implementation

Note de production IRL:

Aussi, pour éviter tout cela, envisagez d'utiliser une configuration proxy/load balancer devant Tomcat avec nginxet/ou haproxy ou similaire car il gérera les actifs statiques et gzip beaucoup plus efficacement et facilement que le modèle de threading Java/Tomcat.

Vous ne vous voulez jeter ' cat dans le bain parce qu'il est occupé à compresser des choses au lieu de servir des demandes (ou plus probablement faire tourner des threads / manger du CPU / tas assis autour d'attendre que les E / S de base de données se produisent pendant l'exécution de votre facture AWS, c'est pourquoi Java/Tomcat traditionnel pourrait ne pas être m'éloigne du sujet...)

Refs: http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#how-to-enable-http-response-compression

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

 155
Author: John Culviner, 2018-05-18 23:08:06

C'est essentiellement la même solution que celle fournie par @andy-wilkinson, mais à partir de Spring Boot 1.0, le customize(...) la méthode a un paramètreConfigurableEmbeddedServletContainer .

Une autre chose qui mérite d'être mentionnée est que Tomcat ne compresse que les types de contenu de text/html, text/xml et text/plain par défaut. Voici un exemple qui prend également 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);
                        }
                    }
            );
        }
    };
}
 13
Author: matsev, 2014-04-17 11:02:02

Sur les versions récentes dans application.yml config:

---

spring:
  profiles: dev

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

---
 11
Author: M. Reza Nasirloo, 2016-07-15 14:38:44

Spring Boot 1.4 Utilisez ceci pour Javascript HTML Json 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
 9
Author: Ronny Shibley, 2016-10-25 11:45:22

Pour activer la compression GZIP, vous devez modifier la configuration de l'instance Tomcat intégrée. Pour ce faire, vous déclarez un bean EmbeddedServletContainerCustomizer dans votre configuration Java, puis enregistrez un TomcatConnectorCustomizer avec lui.

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

Consultez la documentation Tomcat pour plus de détails sur les différentes options de configuration de compression disponibles.

Vous dites que vous voulez activer sélectivement la compression. Selon vos critères de sélection, alors l'approche ci-dessus peut être suffisante. 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 crois que vous devrez effectuer la compression dans votre contrôleur et renvoyer une réponse byte [] avec un en-tête gzip content-encoding.

 4
Author: Andy Wilkinson, 2014-03-02 12:20:36

L'activation de GZip dans Tomcat ne fonctionne pas dans mon projet Spring Boot. J'ai utilisé CompressingFilter a ici.

@Bean
public Filter compressingFilter() {
    CompressingFilter compressingFilter = new CompressingFilter();
    return compressingFilter;
}
 3
Author: user1127860, 2014-09-21 10:18:13

J'ai ajouté pour cela:

Compression du serveur

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

Prises à partir de http://bisaga.com/blog/programming/web-compression-on-spring-boot-application/

 1
Author: Oleksii Kyslytsyn, 2018-03-05 08:15:08

J'ai eu 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 retourné; 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!

 0
Author: Serginho, 2017-11-07 08:54:48