Usando compresión GZIP con Spring Boot/MVC/JavaConfig con RESTful
spring-mvc spring-java-config (8)
En versiones recientes en application.yml
config:
---
spring:
profiles: dev
server:
compression:
enabled: true
mime-types: text/html,text/css,application/javascript,application/json
---
Utilizamos Spring Boot / MVC con java-config basado en anotaciones para una serie de servicios RESTful
y queremos habilitar selectivamente la compresión de flujo HTTP GZIP
en algunas respuestas API.
Sé que puedo hacer esto manualmente en mi controlador y un byte[] @ResponseBody
, sin embargo, preferiríamos confiar en la infraestructura de SpringMVC (filtros / etc) y hacer que automáticamente haga la conversión y compresión JSON (es decir, el método devuelve un POJO).
¿Cómo puedo habilitar la compresión GZIP en ResponseBody o en la instancia incorporada de Tomcat, y de una manera que podamos comprimir selectivamente solo algunas respuestas?
¡Gracias!
PD .: actualmente no tenemos ninguna configuración basada en XML.
Enabeling GZip en Tomcat no funcionó en mi Spring Boot Project. Utilicé CompressingFilter encuentra here .
@Bean
public Filter compressingFilter() {
CompressingFilter compressingFilter = new CompressingFilter();
return compressingFilter;
}
Esta es básicamente la misma solución que se proporciona con @andy-wilkinson, pero a partir de Spring Boot 1.0, el método customize(...) tiene un parámetro ConfigurableEmbeddedServletContainer .
Otra cosa que vale la pena mencionar es que Tomcat solo comprime los tipos de contenido text/html
, text/xml
y text/plain
de forma predeterminada. A continuación se muestra un ejemplo que también admite la compresión 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);
}
}
);
}
};
}
He añadido para esto:
Compresión del servidor
server.compression.enabled=true
server.compression.min-response-size=2048
server.compression.mime-types=application/json,application/xml,text/html,text/xml,text/plain
tomado de http://bisaga.com/blog/programming/web-compression-on-spring-boot-application/
Para habilitar la compresión GZIP, debe modificar la configuración de la instancia incorporada de Tomcat. Para hacerlo, declara un bean EmbeddedServletContainerCustomizer
en su configuración de Java y luego registra un TomcatConnectorCustomizer
con él.
Por ejemplo:
@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);
}
});
}
};
}
Consulte la documentación de Tomcat para obtener más detalles sobre las diversas opciones de configuración de compresión que están disponibles.
Usted dice que quiere activar selectivamente la compresión. Dependiendo de sus criterios de selección, entonces el enfoque anterior puede ser suficiente. Le permite controlar la compresión por parte del agente de usuario de la solicitud, el tamaño de la respuesta y el tipo de mime de la respuesta.
Si esto no satisface sus necesidades, entonces creo que tendrá que realizar la compresión en su controlador y devolver una respuesta de byte [] con un encabezado de codificación de contenido gzip.
Spring Boot 1.4 Use esto para Javascript HTML Json todas las compresiones.
server.compression.enabled: true
server.compression.mime-types: application/json,application/xml,text/html,text/xml,text/plain,text/css,application/javascript
Tuve el mismo problema en mi proyecto Spring Boot + Spring Data al invocar a @RepositoryRestResource
.
El problema es el tipo MIME devuelto; que es application/hal+json
. Agregarlo a la propiedad server.compression.mime-types
resolvió este problema para mí.
Espero que esto ayude a otra persona!
El resto de estas respuestas están desactualizadas y / o son complicadas para algo que debería ser simple IMO (¿por cuánto tiempo ha estado gzip por ahora? Más tiempo que Java ...) De los documentos:
En 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
En 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
Más viejo 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");
}
}
También tenga en cuenta que esto SÓLO funcionará si está ejecutando tomcat integrado:
Si planea implementar un tomcat no incrustado, deberá habilitarlo server.xml http://tomcat.apache.org/tomcat-9.0-doc/config/http.html#Standard_Implementation
IRL Production Note:
También para evitar todo esto, considere usar una configuración de proxy / equilibrador de carga en frente de Tomcat con nginx y / o haproxy o similar, ya que manejará los activos estáticos y gzip MUCHO más eficiente y fácilmente que el modelo de subprocesamiento de Java / Tomcat.
No querrás tirar ''gato en el baño porque está ocupado comprimiendo cosas en lugar de atender peticiones (o más probablemente haciendo girar hilos / comiendo CPU / montón esperando que ocurra IO de la base de datos mientras ejecutas tu factura de AWS que es ¿Por qué Java / Tomcat tradicional podría no ser una buena idea para empezar, dependiendo de lo que estás haciendo, pero estoy divagando ...)