Comment gérer le contenu statique dans Spring MVC?

Je développe une webapp utilisant Spring MVC 3 et le DispatcherServlet intercepte toutes les requêtes comme ça (web.xml):

   app org.springframework.web.servlet.DispatcherServlet   app /  

Maintenant, cela fonctionne comme annoncé, mais comment puis-je gérer le contenu statique? Auparavant, avant d’utiliser les URL RESTful, j’aurais attrapé tous les fichiers * .html par exemple et envoyé cela à DispatcherServlet , mais maintenant c’est un jeu de balle différent.

J’ai un dossier / static / qui inclut / styles /, / js /, / images / etc et je voudrais exclure / static / * du DispatcherServlet .

Maintenant, je pourrais obtenir des ressources statiques en travaillant quand je l’ai fait:

   app /app/  

Mais je veux qu’il ait de bonnes URL (le point avec lequel j’utilise Spring MVC 3), pas la page de destination étant www.domain.com/app/

Je ne veux pas non plus d’une solution couplée à tomcat ou à tout autre conteneur de servlets, et comme il s’agit d’un trafic (relativement) faible, je n’ai pas besoin d’un serveur Web (comme Apache httpd).

Y a-t-il une solution propre à cela?

Comme j’ai passé beaucoup de temps sur cette question, j’ai pensé partager ma solution. Depuis le spring 3.0.4, il existe un paramètre de configuration appelé (plus d’informations sur le site Web de documentation de référence ) qui peut être utilisé pour servir des ressources statiques tout en utilisant DispatchServlet sur la racine de votre site.

Pour l’utiliser, utilisez une structure de répertoire qui ressemble à ceci:

 src/ springmvc/ web/ MyController.java WebContent/ resources/ img/ image.jpg WEB-INF/ jsp/ index.jsp web.xml springmvc-servlet.xml 

Le contenu des fichiers devrait ressembler à ceci:

src / springmvc / web / HelloWorldController.java:

 package springmvc.web; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class HelloWorldController { @RequestMapping(value="/") public Ssortingng index() { return "index"; } } 

WebContent / WEB-INF / web.xml:

    springmvc org.springframework.web.servlet.DispatcherServlet 1   springmvc /   

WebContent / WEB-INF / springmvc-servlet.xml:

                  

WebContent / jsp / index.jsp:

 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 

Page with image

" />

J’espère que cela t’aides 🙂

Ce problème est résolu au spring 3.0.4.RELEASE où vous pouvez utiliser l’élément de configuration dans votre fichier de configuration du répartiteur de spring.

Vérifier la documentation du spring

Dans Spring 3.0.x, ajoutez les éléments suivants à votre fichier servlet-config.xml (le fichier configuré dans web.xml comme contexteConfigLocation. Vous devez également append l’espace de noms mvc, mais uniquement google si vous ne savez pas comment !;)

Ça marche pour moi

  

Cordialement

Ayub Malik

Si je comprends bien votre problème, je pense avoir trouvé une solution à votre problème:

J’ai eu le même problème où la sortie brute a été affichée sans aucun style CSS, javascripts ou fichiers jquery trouvés.

Je viens d’append des mappages au servlet “par défaut”. Ce qui suit a été ajouté au fichier web.xml:

   default *.css   default *.js  

Cela devrait filtrer les requêtes de fichiers javascript et css de l’object DispatcherRequest.

Encore une fois, je ne sais pas si c’est ce que vous recherchez, mais cela a fonctionné pour moi. Je pense que “default” est le nom du servlet par défaut dans JBoss. Pas trop sûr de ce que c’est pour les autres serveurs.

Il y a un autre message de débordement de stack qui a une excellente solution .

Il ne semble pas être spécifique à Tomcat, est simple et fonctionne très bien. J’ai essayé quelques solutions dans cet article avec spring mvc 3.1, mais j’ai eu des problèmes pour obtenir mon contenu dynamic.

En bref, il est dit d’append un mappage de servlet comme ceci:

  default /images/*  

Je viens de me débattre avec ce problème dans Spring MVC 3.0 et j’ai initialement opté pour l’option UrlRewriteFilter. Cependant, je n’étais pas content de cette solution car elle “ne me semblait pas juste” (je ne suis pas le seul – voir le lien ci-dessus pour les forums de spring où le mot “hack” apparaît quelques fois).

J’ai donc trouvé une solution similaire à “Unknown (Google)” ci-dessus, mais j’ai eu l’idée d’avoir tout le contenu statique à partir de / static / (extrait de la version Spring Roo de l’application Pet Store). Le servlet “default” ne fonctionnait pas pour moi, mais le Spring Webflow ResourceServlet le faisait (également depuis l’application générée par Spring Roo).

Web.xml:

  mainDispatcher org.springframework.web.servlet.DispatcherServlet 2   Resource Servlet org.springframework.js.resource.ResourceServlet 1   mainDispatcher /   Resource Servlet /static/*  

Le seul changement que j’ai apporté aux JSP consistait à append le chemin / static / aux URL pour CSS, JS et les images. Par exemple, “$ {pageContext.request.contextPath} /static/css/screen.css”.

pour les utilisateurs de Maven, la dépendance pour “org.springframework.js.resource.ResourceServlet” est la suivante:

  org.springframework.webflow org.springframework.js 2.0.8.RELEASE  

J’ai trouvé un moyen de contourner ce problème en utilisant le filtre à urlrewrite de tuckey. N’hésitez pas à donner une meilleure réponse si vous en avez une!

Dans web.xml:

  UrlRewriteFilter org.tuckey.web.filters.urlrewrite.UrlRewriteFilter   UrlRewriteFilter /*   app org.springframework.web.servlet.DispatcherServlet   app /app/*  

Dans urlrewrite.xml:

   / /app/   ^([^\.]+)$ /app/$1   /app/** /$1  

Cela signifie que tout uri avec un ‘.’ en elle (comme style.css par exemple) ne sera pas réécrit.

Ma propre expérience avec ce problème est la suivante. La plupart des pages Web et des livres liés à Spring semblent suggérer que la syntaxe la plus appropriée est la suivante.

   

La syntaxe ci-dessus suggère que vous pouvez placer vos ressources statiques (CSS, JavaScript, images) dans un dossier nommé “resources” dans la racine de votre application, par exemple / webapp / resources /.

Cependant, dans mon expérience (j’utilise Eclipse et le plugin Tomcat), la seule approche qui fonctionne est si vous placez votre dossier de ressources dans WEB_INF (ou META-INF). Donc, la syntaxe que je recommande est la suivante.

   

Dans votre JSP (ou similaire), référencez la ressource comme suit.

  

Inutile de mentionner que toute la question n’a été soulevée que parce que je voulais que mon servlet Spring Dispatcher (contrôleur frontal) intercepte tout, tout ce qui est dynamic. J’ai donc ce qui suit dans mon web.xml.

  front-controller  org.springframework.web.servlet.DispatcherServlet  1    front-controller /  

Enfin, comme j’utilise les meilleures pratiques actuelles, j’ai ce qui suit dans mon servlet de contrôleur frontal xml (voir ci-dessus).

  

Et j’ai l’implémentation suivante dans mon implémentation de contrôleur, pour m’assurer d’avoir une méthode par défaut pour traiter toutes les demandes entrantes.

 @RequestMapping("/") 

J’espère que ça aide.

J’ai eu le même problème et j’ai trouvé la réponse de Joris très utile. Mais en plus je dois append

  

dans le fichier de configuration de servlet. Sans cela, le mappage des ressources ne fonctionnera pas et tous les gestionnaires cesseront de fonctionner. J’espère que cela aidera quelqu’un.

Le URLRewrite est en quelque sorte un “hack” si vous voulez l’appeler ainsi. En fin de compte, vous réinventez la roue; comme il existe déjà des solutions. Une autre chose à retenir est Http Server = Static content & App server = contenu dynamic (voici comment ils ont été conçus). En déléguant les responsabilités appropriées à chaque serveur, vous maximisez l’efficacité… mais aujourd’hui, ce n’est probablement qu’un problème dans les environnements critiques et quelque chose comme Tomcat fonctionnerait probablement bien dans les deux rôles la plupart du temps; mais c’est quand même quelque chose à garder à l’esprit.

Je l’ai résolu de cette façon:

  Spring MVC Dispatcher Servlet /   default *.jpg   default *.png   default *.gif   default *.js   default *.css  

Cela fonctionne sur Tomcat et ofcourse Jboss. Cependant, à la fin, j’ai décidé d’utiliser la solution proposée par Spring (comme mentionné par Rozky), qui est beaucoup plus portable.

A partir du spring 3, toutes les ressources doivent être cartographiées différemment. Vous devez utiliser la balise pour spécifier l’emplacement des ressources.

Exemple :

  

De cette manière, vous dirigez le servlet du répartiteur dans les ressources du répertoire pour rechercher le contenu statique.

Ma façon de résoudre ce problème consiste à placer toutes vos actions avec un préfixe spécifique tel que “web” ou “service” et à configurer que toutes les URL avec ce préfixe seront interceptées par le DispatcherServlet.

Je viens d’append trois règles avant la règle par défaut du spring (/ **) à urlrewritefilter de tuckey (urlrewrite.xml) pour résoudre le problème

     / /app/welcome   /scripts/** /scripts/$1   /styles/** /styles/$1   /images/** /images/$1   /** /app/$1   /app/** /$1   

Je sais qu’il existe quelques configurations pour utiliser le contenu statique, mais ma solution est de créer un dossier d’application Web en bloc dans votre Tomcat. Cette “webapp en vrac” ne sert que tout le contenu statique sans servir d’applications. C’est une solution facile et sans douleur pour servir des contenus statiques à votre application Web de spring.

Par exemple, j’utilise deux dossiers Webapp sur mon tomcat.

  1. springapp : il exécute uniquement une application web Spring sans contenu statique comme imgs, js ou css. (dédié aux applications de spring.)
  2. ressources : il ne sert que le contenu statique sans JSP, servlet ou toute autre application Web Java. (dédié aux contenus statiques)

Si je veux utiliser javascript, j’ajoute simplement l’URI pour mon fichier javascript.

EX> /resources/path/to/js/myjavascript.js

Pour les images statiques, j’utilise la même méthode.

EX> /resources/path/to/img/myimg.jpg

Enfin, j’ai mis ” sécurité-contrainte ” sur mon tomcat pour bloquer l’access au répertoire réel. Je mets “personne” en roulis à la contrainte pour que la page génère “erreur 403 interdite” quand les gens essayaient d’accéder au chemin du contenu statique.

Jusqu’à présent, cela fonctionne très bien pour moi. J’ai également remarqué que de nombreux sites Web populaires, tels qu’Amazon, Twitter et Facebook, utilisent différents URI pour diffuser des contenus statiques. Pour le savoir, cliquez avec le bouton droit sur n’importe quel contenu statique et vérifiez leur URI.

J’ai utilisé les deux méthodes, urlrewrite et annotation basées sur Spring mvc 3.0.x, et trouvé que l’approche basée sur les annotations est la plus appropriée

   

Dans le cas de urlrewrite, vous devez définir beaucoup de règles et, parfois, obtenir une exception de classe non trouvée pour UrlRewriteFilter car elle a déjà fourni la dépendance pour elle. J’ai trouvé que cela se produisait en raison de la présence d’une dépendance transitive, de sorte qu’une seule étape augmentera et que vous devrez exclure cette dépendance de pom.xml en utilisant

  tags. 

Donc, l’approche basée sur l’annotation sera la bonne affaire.

Cela a fait le vrai boulot dans mon cas

dans web.xml:

 ...  default /images/* /css/* /javascripts/*   spring-mvc-dispatcher /  

Après avoir rencontré et passé par le même processus de prise de décision décrit ici, j’ai décidé d’utiliser la proposition ResourceServlet qui fonctionne très bien.

Notez que vous obtenez plus d’informations sur l’utilisation de webflow dans votre processus de génération de maven ici: http://static.springsource.org/spring-webflow/docs/2.0.x/reference/html/ch01s05.html

Si vous utilisez le référentiel central Maven standard, l’artefact est (en face du regroupement de sources springs mentionné ci-dessus):

  org.springframework.webflow spring-js 2.0.9.RELEASE  

Cela peut être réalisé de trois manières au moins.

Solutions :

  • exposer le HTML en tant que fichier de ressources
  • demander à JspServlet de gérer également les requêtes * .html
  • écrivez votre propre servlet (ou passez à une autre demande de servlet existante à * .html).

Pour obtenir des exemples de code complets, reportez-vous à ma réponse dans un autre article: Comment mapper les demandes au fichier HTML dans Spring MVC?

Le problème est avec URLPattern

Changez votre modèle d’URL sur le mappage de votre servlet de “/” à “/ *”

     

et si vous souhaitez utiliser la configuration basée sur des annotations, utilisez le code ci-dessous

 @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable(); } 

Pour la configuration de spring basée sur Java, vous pouvez utiliser les éléments suivants

Utilisation de ResourceHandlerRegistry qui stocke les enregistrements des gestionnaires de ressources pour la gestion des ressources statiques.

Plus d’informations @ WebMvcConfigurerAdapter qui définit des méthodes de rappel pour personnaliser la configuration Java pour Spring MVC activée via @EnableWebMvc.

 @EnableWebMvc @Configurable @ComponentScan("package.to.scan") public class WebConfigurer extends WebMvcConfigurerAdapter { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/static_resource_path/*.jpg").addResourceLocations("server_destination_path"); }