Statische Ressourcen mit Spring bereitstellen
1. Überblick
In diesem Artikel wird erläutert, wieserve static resources with Spring verwendet werden - sowohl mit XML- als auch mit Java-Konfiguration.
Weitere Lektüre:
Cacheable Static Assets mit Spring MVC
Dieser Artikel beschreibt, wie Sie Ihre statischen Assets wie Javascript- und CSS-Dateien zwischenspeichern, wenn Sie sie mit Spring MVC bereitstellen.
Einführung in WebJars
Eine schnelle und praktische Anleitung zur Verwendung von WebJars mit Spring.
Minimierung von JS- und CSS-Assets mit Maven
Eine Kurzanleitung zur Verwendung von Maven zum Minimieren von Javascript- und CSS-Dateien in einem Java-Webprojekt.
2. XML-Konfiguration
Wenn Sie bei der XML-basierten Konfiguration den alten Weg gehen müssen, können Sie das Elementmvc:resourcesgut nutzen, um auf den Speicherort von Ressourcen mit einem bestimmten öffentlichen URL-Muster zu verweisen.
Beispiel: In der folgenden Zeile werden alle Anfragen nach Ressourcen mit einem öffentlichen URL-Muster wie "/resources/**" bearbeitet, indem im Verzeichnis "/resources/" unter dem Stammordner in unserer Anwendung gesucht wird.
Jetzt können wir wie auf der folgenden HTML-Seite auf eine CSS-Datei zugreifen:
Beispiel 2.1.
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
" rel="stylesheet">
Home
Hello world!
3. DieResourceHttpRequestHandler
Spring 3.1. führteResourceHandlerRegistry ein, umResourceHttpRequestHandlers für die Bereitstellung statischer Ressourcen aus dem Klassenpfad, dem WAR oder dem Dateisystem zu konfigurieren. Wir können dieResourceHandlerRegistry programmgesteuert in unserer Webkontext-Konfigurationsklasse konfigurieren.
3.1. Bereitstellen einer im WAR gespeicherten Ressource
Um dies zu veranschaulichen, verwenden wir dieselbe URL wie zuvor, um aufmyCss.css zu verweisen. Jetzt befindet sich die eigentliche Datei im Ordnerwebapp/resourcesder WAR, in dem statische Ressourcen beim Bereitstellen abgelegt werden sollten Spring 3.1+ Anwendungen:
Beispiel 3.1.1.
@Configuration
@EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/resources/**")
.addResourceLocations("/resources/");
}
}
Lassen Sie uns das Beispielbit analysieren. Wir konfigurieren zuerst den externen zugewandten URI-Pfad, indem wir einen Ressourcenhandler definieren. Anschließend ordnen wir diesen externen zugewandten URI-Pfad intern dem physischen Pfad zu, in dem sich die Ressourcen tatsächlich befinden.
Mit dieser einfachen und dennoch flexiblen API können wir natürlich mehrere Ressourcenhandler definieren.
Nun - die folgende Zeile auf einerhtml-Seite würde uns diemyCss.css-Ressource imwebapp/resources-Verzeichnis anzeigen:
" rel="stylesheet">
3.2. Bereitstellen einer im Dateisystem gespeicherten Ressource
Nehmen wir an, wir möchten eine Ressource bereitstellen, die im Verzeichnis/opt/files/ gespeichert ist, wenn eine Anforderung für die öffentliche URL eingeht, die dem Muster entspricht:/files/**. Wir konfigurieren einfach das URL-Muster und ordnen es diesem bestimmten Speicherort auf der Festplatte zu:
Beispiel 3.2.1.
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/files/**")
.addResourceLocations("file:/opt/files/");
}
* (Für Windows-Benutzer: Das anaddResourceLocations für dieses Beispiel übergebene Argument lautet "file:///C:/opt/files/").
Sobald wir den Ressourcenspeicherort konfiguriert haben, können wir das zugeordnete URL-Muster in unserenhome.html bisload an image stored in the file system wie folgt verwenden:
Beispiel 3.2.2.
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
" rel="stylesheet">
Home
Hello world!
">
3.3. Mehrere Standorte für eine Ressource konfigurieren
Was ist, wenn wir eine Ressource an mehreren Standorten suchen möchten?
Mit der MethodeaddResourceLocationskönnen mehrere Standorte eingeschlossen werden. Die Liste der Standorte wird nacheinander durchsucht, bis die Ressource gefunden wurde. Schauen wir uns Beispiel 3.3.1 an.
Beispiel 3.3.1
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/resources/**")
.addResourceLocations("/resources/","classpath:/other-resources/");
}
Die folgende Curl-Anforderung zeigt die SeiteHello.htmlan, die entweder im Ordnerwebappp/resources der Anwendung oder im Ordnerother-resources im Klassenpfad gespeichert ist.
curl -i http://localhost:8080/handling-spring-static-resources/resources/Hello.html
4. Die neuenResourceResolvers
Frühling 4.1. bietet mit den neuenResourcesResolvers verschiedene Arten von Ressourcenauflösern, mit denen die Browserleistung beim Laden statischer Ressourcen optimiert werden kann. Diese Resolver können im Browser verkettet und zwischengespeichert werden, um die Verarbeitung von Anforderungen zu optimieren.
4.1. DiePathResourceResolver
Dies ist der einfachste Resolver und dient dazu, eine Ressource mit einem öffentlichen URL-Muster zu finden. Wenn zuResourceChainRegistration keinResourceResolver hinzugefügt wird, ist dies der Standardauflöser.
Sehen wir uns ein Beispiel an:
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/resources/**")
.addResourceLocations("/resources/","/other-resources/")
.setCachePeriod(3600)
.resourceChain(true)
.addResolver(new PathResourceResolver());
}
Dinge zu beachten:
-
Wir registrieren diePathResourceResolver in der Ressourcenkette als die einzigenResourceResolver in der Ressourcenkette. Siehe Abschnitt 4.3. um zu überprüfen, wie mehr als einResourceResolver verkettet werden.
-
Die bereitgestellten Ressourcen werden 3600 Sekunden lang im Browser zwischengespeichert.
-
Die Kette wird schließlich mit der MethoderesourceChain(true) konfiguriert.
Nun - der HTML-Code, der in Verbindung mitPathResourceResolver das Skriptfoo.js entweder inwebapp/resources des Ordnerswebapp/other-resources findet:
">
4.2. DieEncodedResourceResolver
Dieser Resolver versucht, eine codierte Ressource basierend auf dem Anforderungsheaderwert vonAccept-Encodingzu finden.
Beispielsweise müssen wir möglicherweise die Bandbreite optimieren, indem wir die komprimierte Version einer statischen Ressource mithilfe der Inhaltscodierung vongzipbereitstellen.
Um einEncodedResourceResolver, zu konfigurieren, müssen wir es nur inResourceChain konfigurieren, genauso wie wirPathResourceResolver konfiguriert haben, wie in der folgenden Codezeile:
registry
.addResourceHandler("/other-files/**")
.addResourceLocations("file:/Users/Me/")
.setCachePeriod(3600)
.resourceChain(true)
.addResolver(new EncodedResourceResolver());
Standardmäßig istEncodedResourceResolver so konfiguriert, dass es die Codierungenbr undgzipunterstützt.
Bei der folgenden Anforderung voncurlwird die komprimierte Version der DateiHome.html abgerufen, die sich im Dateisystem im VerzeichnisUsers/Me/befindet:
curl -H "Accept-Encoding:gzip"
http://localhost:8080/handling-spring-static-resources/other-files/Hello.html
Beachten Sie, wiewe are setting the header’s “Accept-Encoding” value to gzip - dies ist wichtig, da dieser bestimmte Resolver nur dann aktiviert wird, wenn der gzip-Inhalt für die Antwort gültig ist.
Beachten Sie schließlich, dass die komprimierte Version wie zuvor für den Zeitraum verfügbar bleibt, in dem sie im Browser zwischengespeichert wird - in diesem Fall 3600 Sekunden.
4.3. VerkettungResourceResolvers
Um die Ressourcensuche zu optimieren, kannResourceResolvers die Verarbeitung von Ressourcen an andere Resolver delegieren. Der einzige Resolver, der nicht an die Kette delegieren kann, istPathResourceResolver, der am Ende der Kette hinzugefügt werden sollte.
WennresourceChain nicht auftrue eingestellt ist, wird standardmäßig nurPathResourceResolver verwendet, um Ressourcen bereitzustellen. In Beispiel 4.3.1. Wir verketten diePathResourceResolver, um die Ressource aufzulösen, wenn dieGzipResourceResolver nicht erfolgreich sind.
Beispiel 4.3.1.
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/js/**")
.addResourceLocations("/js/")
.setCachePeriod(3600)
.resourceChain(true)
.addResolver(new GzipResourceResolver())
.addResolver(new PathResourceResolver());
}
Nachdem wir das/js/**-Muster zuResourceHandler hinzugefügt haben, können Sie diefoo.js-Ressource, die sich im Verzeichniswebapp/js/ befindet, wie in Beispiel 4.3 in unserehome.html-Seite aufnehmen .2.
Beispiel 4.3.2.
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
" rel="stylesheet" />
">
Home
This is Home!
" />
5. Zusätzliche Sicherheitskonfiguration
Bei Verwendung von Spring Security ist es wichtig, den Zugriff auf die statischen Ressourcen zuzulassen. Wir müssen die entsprechenden Berechtigungen für den Zugriff auf die Ressourcen-URLs hinzufügen:
6. Fazit
In diesem Artikel haben wir verschiedene Möglichkeiten erläutert, wie statische Ressourcen in einer Spring-Anwendung bereitgestellt werden können.
Die XML-basierte Ressourcenkonfiguration ista “legacy” option und kann verwendet werden, wenn Sie die Java-Konfigurationsroute noch nicht durchlaufen können.
Spring 3.1. came out withist eine grundlegende programmatische Alternative durch dasResourceHandlerRegistry-Objekt.
Und schließlich - das neue Out-of-the-Box-ObjektResourceResolvers undResourceChainRegistrationshipped with Spring 4.1. bieten Funktionen zur Optimierung des Ressourcenladevorgangs wie Caching und Verkettung von Ressourcenhandlern, um die Effizienz bei der Bereitstellung statischer Ressourcen zu verbessern.
Wie immer ist das vollständige Beispielover on Github verfügbar.