Używamy Spring Boot / MVC z opartą na adnotacjach java-config dla serii RESTful
usług i chcemy selektywnie włączyć HTTP GZIP
kompresję strumienia w niektórych odpowiedziach API.
Wiem, że mogę to zrobić ręcznie w moim kontrolerze i a byte[] @ResponseBody
, jednak wolelibyśmy polegać na infrastrukturze SpringMVC (filtry / itp.) I automatycznie wykonywać konwersję i kompresję JSON (tj. Metoda zwraca POJO).
Jak mogę włączyć kompresję GZIP w instancji ResponseBody lub osadzonej Tomcat, aby w sposób selektywny kompresować tylko niektóre odpowiedzi?
Dzięki!
PS .: Obecnie nie mamy żadnej konfiguracji opartej na XML.
java
rest
spring-mvc
gzip
spring-java-config
user3182614
źródło
źródło
Odpowiedzi:
Pozostałe odpowiedzi są nieaktualne i / lub przesadnie skomplikowane dla czegoś, co powinno być prostym IMO (jak długo istnieje gzip? Dłużej niż Java ...) Z dokumentacji:
W application.properties 1.3+
# 🗜️🗜️🗜️ server.compression.enabled=true # opt in to content types server.compression.mime-types=application/json,application/xml,text/html,text/xml,text/plain,application/javascript,text/css # not worth the CPU cycles at some point, probably server.compression.min-response-size=10240
W application.properties 1.2.2 - <1.3
Starsze niż 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"); } }
Zwróć również uwagę, że będzie to działać TYLKO, jeśli używasz osadzonego tomcat:
Jeśli planujesz wdrożyć na nie osadzonym tomcat, musisz go włączyć w server.xml http://tomcat.apache.org/tomcat-9.0-doc/config/http.html#Standard_Implementation
Uwaga dotycząca produkcji IRL:
Również, aby uniknąć tego wszystkiego, rozważ użycie konfiguracji proxy / load balancera przed Tomcat z nginx i / lub haproxy lub podobnym, ponieważ będzie on obsługiwał statyczne zasoby i gzip DUŻO wydajniej i łatwiej niż model wątków Java / Tomcat.
Nie chcesz wrzucać kota do wanny, ponieważ zajmuje się on kompresowaniem rzeczy zamiast obsługiwać żądania (lub bardziej prawdopodobne, że kręci wątki / zjada procesor / stertę, czekając na wystąpienie operacji we / wy bazy danych podczas uruchamiania rachunku AWS, który jest dlaczego tradycyjna Java / Tomcat może nie być dobrym pomysłem na początek, w zależności od tego, co robisz, ale dygresję ...)
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
źródło
TomcatConnectorCustomizer
instancji w kontekście aplikacji; muszą być programowo zarejestrowaneTomcatEmbeddedServletContainerFactory
server.compression.min-response-size=10240
Najnowsze wersje w
application.yml
konfiguracji:--- spring: profiles: dev server: compression: enabled: true mime-types: text/html,text/css,application/javascript,application/json ---
źródło
Jest to w zasadzie to samo rozwiązanie, co @ andy-wilkinson, ale od wersji Spring Boot 1.0 metoda customizacji (...) ma parametr ConfigurableEmbeddedServletContainer .
Inna sprawa, że to warto wspomnieć, że Tomcat kompresuje tylko treści rodzajów
text/html
,text/xml
atext/plain
domyślnie. Poniżej znajduje się przykład, który obsługuje również kompresję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); } } ); } }; }
źródło
Accept-Encoding: gzip,deflate
nagłówek, jeśli używasz curl:curl -i -H 'Accept-Encoding: gzip,deflate' http://url.to.your.server
Spring Boot 1.4 Użyj tego dla wszystkich kompresji JavaScript HTML Json.
server.compression.enabled: true server.compression.mime-types: application/json,application/xml,text/html,text/xml,text/plain,text/css,application/javascript
źródło
Content-Encoding
:gzip
Dodałem do tego:
Kompresja serwera
server.compression.enabled=true server.compression.min-response-size=2048 server.compression.mime-types=application/json,application/xml,text/html,text/xml,text/plain
pobrane z http://bisaga.com/blog/programming/web-compression-on-spring-boot-application/
źródło
Włączanie GZip w Tomcat nie działa w moim projekcie Spring Boot. Użyłem CompressingFilter znalezionego tutaj .
@Bean public Filter compressingFilter() { CompressingFilter compressingFilter = new CompressingFilter(); return compressingFilter; }
źródło
Aby włączyć kompresję GZIP, należy zmodyfikować konfigurację osadzonej instancji Tomcat. Aby to zrobić, deklarujesz
EmbeddedServletContainerCustomizer
komponent bean w konfiguracji Java, a następnie rejestrujesz plikTomcatConnectorCustomizer
go w nim.Na przykład:
@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); } }); } }; }
Więcej informacji na temat różnych dostępnych opcji konfiguracji kompresji można znaleźć w dokumentacji Tomcat .
Mówisz, że chcesz selektywnie włączyć kompresję. W zależności od kryteriów wyboru powyższe podejście może być wystarczające. Umożliwia sterowanie kompresją przez agenta użytkownika żądania, rozmiar odpowiedzi i typ MIME odpowiedzi.
Jeśli to nie spełnia twoich potrzeb, uważam, że będziesz musiał wykonać kompresję w kontrolerze i zwrócić odpowiedź byte [] z nagłówkiem kodowania treści gzip.
źródło
Miałem ten sam problem w moim projekcie Spring Boot + Spring Data podczas wywoływania pliku
@RepositoryRestResource
.Problem polega na zwróceniu typu MIME; który jest
application/hal+json
. Dodanie go doserver.compression.mime-types
nieruchomości rozwiązało ten problem za mnie.Mam nadzieję, że to pomoże komuś innemu!
źródło