Servir des ressources statiques avec Spring
1. Vue d'ensemble
Cet article explique commentserve static resources with Spring - en utilisant à la fois la configuration XML et Java.
Lectures complémentaires:
Actifs statiques pouvant être mis en cache avec Spring MVC
Cet article explique comment mettre en cache vos actifs statiques tels que les fichiers Javascript et CSS lors de leur utilisation avec Spring MVC.
Introduction à WebJars
Un guide rapide et pratique sur l'utilisation de WebJars avec Spring.
Minification des actifs JS et CSS avec Maven
Guide rapide d'utilisation de Maven pour réduire au minimum les fichiers Javascript et CSS dans un projet Web Java.
2. Configuration XML
Si vous devez utiliser l'ancienne méthode avec une configuration XML, vous pouvez utiliser à bon escient l'élémentmvc:resources pour pointer vers l'emplacement des ressources avec un modèle d'URL publique spécifique.
Par exemple - la ligne suivante servira toutes les demandes de ressources arrivant avec un modèle d'URL publique comme «/resources/**» en recherchant dans le répertoire «/resources/» sous le dossier racine de notre application.
Maintenant, nous pouvons accéder à un fichier CSS comme dans la page html suivante:
Exemple 2.1.
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
" rel="stylesheet">
Home
Hello world!
3. LesResourceHttpRequestHandler
Spring 3.1. a introduit lesResourceHandlerRegistry pour configurer lesResourceHttpRequestHandler pour servir les ressources statiques à partir du chemin de classe, du WAR ou du système de fichiers. Nous pouvons configurer lesResourceHandlerRegistry par programme dans notre classe de configuration de contexte Web.
3.1. Servir une ressource stockée dans le WAR
Pour illustrer cela, nous utiliserons la même URL que précédemment pour pointer versmyCss.css, mais maintenant le fichier réel sera situé dans le dossierwebapp/resources du WAR, où les ressources statiques doivent être placées lors du déploiement Applications Spring 3.1+:
Exemple 3.1.1.
@Configuration
@EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/resources/**")
.addResourceLocations("/resources/");
}
}
Analysons le bit d'exemple. Nous configurons d’abord le chemin d’URI externe en ajoutant un gestionnaire de ressources. Nous mappons ensuite ce chemin d'URI externe en interne vers le chemin physique où se trouvent les ressources.
Nous pouvons bien entendu définir plusieurs gestionnaires de ressources à l'aide de cette API simple mais flexible.
Maintenant - la ligne suivante dans une pagehtml nous obtiendrait la ressourcemyCss.css dans le répertoirewebapp/resources:
" rel="stylesheet">
3.2. Servir une ressource stockée dans le système de fichiers
Disons que nous voulons servir une ressource stockée dans le répertoire/opt/files/ chaque fois qu'une demande arrive pour l'URL publique correspondant au modèle:/files/**. Nous configurons simplement le modèle d'URL et le mappons vers cet emplacement particulier sur le disque:
Exemple 3.2.1.
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/files/**")
.addResourceLocations("file:/opt/files/");
}
* (Pour les utilisateurs de Windows: l'argument passé àaddResourceLocations pour cet exemple serait «file:///C:/opt/files/»).
Une fois que nous avons configuré l'emplacement de la ressource, nous pouvons utiliser le modèle d'URL mappé dans noshome.html àload an image stored in the file system comme suit:
Exemple 3.2.2.
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
" rel="stylesheet">
Home
Hello world!
">
3.3. Configuration de plusieurs emplacements pour une ressource
Que faire si nous voulons rechercher une ressource dans plus d'un endroit?
Nous pouvons inclure plusieurs emplacements avec la méthodeaddResourceLocations. La liste des emplacements fera l'objet d'une recherche dans l'ordre jusqu'à ce que la ressource soit trouvée. Jetons un coup d'oeil à l'exemple 3.3.1.
Exemple 3.3.1
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/resources/**")
.addResourceLocations("/resources/","classpath:/other-resources/");
}
La requête curl suivante affichera la pageHello.html stockée dans le dossierwebappp/resources de l’application ou dans le dossierother-resources dans le chemin de classe.
curl -i http://localhost:8080/handling-spring-static-resources/resources/Hello.html
4. Les nouveauxResourceResolvers
Printemps 4.1. fournit - avec les nouveauxResourcesResolvers - différents types de résolveurs de ressources qui peuvent être utilisés pour optimiser les performances du navigateur lors du chargement de ressources statiques. Ces résolveurs peuvent être chaînés et mis en cache dans le navigateur pour optimiser le traitement des demandes.
4.1. LesPathResourceResolver
C'est le résolveur le plus simple et son but est de trouver une ressource à partir d'un modèle d'URL public. En fait, si aucunResourceResolver n'est ajouté auxResourceChainRegistration, c'est le résolveur par défaut.
Voyons un exemple:
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/resources/**")
.addResourceLocations("/resources/","/other-resources/")
.setCachePeriod(3600)
.resourceChain(true)
.addResolver(new PathResourceResolver());
}
Les choses à noter:
-
Nous enregistrons lesPathResourceResolver dans la chaîne de ressources comme les seulsResourceResolver de celle-ci. Voir section 4.3. pour vérifier comment chaîner plus d'unResourceResolver.
-
Les ressources servies seront mises en cache dans le navigateur pendant 3600 secondes.
-
La chaîne est enfin configurée avec la méthoderesourceChain(true).
Maintenant - le code html qui, en conjonction avec lesPathResourceResolver, localise le scriptfoo.js soit dans leswebapp/resources du dossierwebapp/other-resources:
">
4.2. LesEncodedResourceResolver
Ce résolveur tente de trouver une ressource codée en fonction de la valeur d'en-tête de demandeAccept-Encoding.
Par exemple, nous pouvons avoir besoin d'optimiser la bande passante en servant la version compressée d'une ressource statique à l'aide du codage de contenugzip.
Pour configurer unEncodedResourceResolver,, il suffit de le configurer dans lesResourceChain tout comme nous avons configuré lesPathResourceResolver, comme dans la ligne de code suivante:
registry
.addResourceHandler("/other-files/**")
.addResourceLocations("file:/Users/Me/")
.setCachePeriod(3600)
.resourceChain(true)
.addResolver(new EncodedResourceResolver());
Par défaut, leEncodedResourceResolver est configuré pour prendre en charge les codagesbr etgzip.
Ainsi, la requêtecurl suivante obtiendra la version zippée du fichierHome.html situé dans le système de fichiers dans le répertoireUsers/Me/:
curl -H "Accept-Encoding:gzip"
http://localhost:8080/handling-spring-static-resources/other-files/Hello.html
Remarquez commentwe are setting the header’s “Accept-Encoding” value to gzip - ceci est important car ce résolveur particulier ne se déclenchera que si le contenu gzip est valide pour la réponse.
Enfin, notez que, comme auparavant, la version compressée restera disponible pendant la période de mise en cache dans le navigateur - qui dans ce cas est de 3 600 secondes.
4.3. ChaînageResourceResolvers
Pour optimiser la recherche de ressources,ResourceResolvers peut déléguer la gestion des ressources à d'autres résolveurs. Le seul résolveur qui ne peut pas déléguer à la chaîne est lePathResourceResolver qui doit être ajouté à la fin de la chaîne.
En fait, siresourceChain n'est pas défini surtrue, alors par défaut, seul unPathResourceResolver sera utilisé pour servir les ressources. Dans l'exemple 4.3.1. nous chaînons lesPathResourceResolver pour résoudre la ressource si leGzipResourceResolver échoue.
Exemple 4.3.1.
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/js/**")
.addResourceLocations("/js/")
.setCachePeriod(3600)
.resourceChain(true)
.addResolver(new GzipResourceResolver())
.addResolver(new PathResourceResolver());
}
Maintenant que nous avons ajouté le modèle/js/** auxResourceHandler, incluons la ressourcefoo.js située dans le répertoirewebapp/js/ dans notre pagehome.html comme dans l'exemple 4.3 .2.
Exemple 4.3.2.
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
" rel="stylesheet" />
">
Home
This is Home!
" />
5. Configuration de sécurité supplémentaire
Si vous utilisez Spring Security, il est important d'autoriser l'accès aux ressources statiques. Nous devrons ajouter les autorisations correspondantes pour accéder aux URL de ressources:
6. Conclusion
Dans cet article, nous avons illustré différentes manières de servir des ressources statiques dans une application Spring.
La configuration des ressources basée sur XML esta “legacy” option qui peut être utilisée si vous ne pouvez pas encore emprunter la route de configuration Java.
Spring 3.1. came out with une alternative programmatique de base via son objetResourceHandlerRegistry.
Et enfin - le nouvel objetResourceResolvers etResourceChainRegistrationshipped with Spring 4.1 prêt à l'emploi. offre des fonctionnalités d'optimisation du chargement des ressources telles que la mise en cache et le chaînage des gestionnaires de ressources pour améliorer l'efficacité de la gestion des ressources statiques.
Comme toujours, l'exemple complet est disponibleover on Github.