SpringMVC peut-il être configuré pour traiter toutes les demandes, mais exclure les répertoires de contenu statique?

Si je mappe mon application Spring pour traiter toutes les demandes entrantes (‘/ *’), les demandes de contenu statique renvoient les 404. Par exemple, une demande pour “myhost.com/css/global.css” renverrait un 404, même si la ressource existe, car Spring intercepte la demande.

L’alternative consiste à mapper SpringMVC sur un sous-répertoire (par exemple ‘/ home / ‘), mais dans ce cas, vous devez transmettre ce répertoire dans tous les liens de l’application. Existe-t-il un moyen de mapper SpringMVC sur ‘/ ‘ et d’exclure un ensemble de répertoires du traitement?

Ma configuration web.xml actuelle est la suivante:

 springApp org.springframework.web.servlet.DispatcherServlet 2   springApp /home/*  

Je souhaiterais que la cartographie soit similaire à celle-ci:

   springApp /* /css/*,/js/*  

Ce type de chose est-il possible?

Si vous voulez faire cela avec Spring seulement, c’est possible mais un peu en désordre:

  1. Vous devrez soit utiliser un SimpleUrlHandlerMapping pour lequel vous pouvez spécifier explicitement des modèles d’URL qui doivent être mappés aux contrôleurs, soit l’étendre pour prendre en charge les URL “ignore” telles que “css / **”.
  2. Vous devrez écrire votre propre implémentation HttpRequestHandler qui consisterait essentiellement en un appel à “getServletContext (). GetRequestDsipatcher (). Include ()” pour renvoyer la ressource demandée telle quelle.
  3. Vous devrez enregistrer ce gestionnaire comme defaultHandler pour le SimpleUrlHandlerMapping ci-dessus.

Une fois que tout cela est fait, toutes les requêtes qui ne peuvent pas être mappées à vos contrôleurs seront transmises à votre HttpRequestHandler et servies “telles HttpRequestHandler “.

REMARQUE: cette réponse s’applique uniquement à Spring 3.0.4+

(BTW, cette question a également été traitée ici: Spring servant du contenu statique avec mvc: ressources, xsd invalide )

Découvrez le projet Spring mvc-showcase dans le référentiel des exemples de subversion de Spring. Il montre exactement ce que vous voulez faire, à savoir que vous pouvez définir des ressources statiques qui ne seront pas traitées par DisapatcherServlet. Voir le fichier /mvc-showcase/src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml . Voici un extrait de la manière dont je gère ces exclusions, où JS, CSS et les images sont dans la racine de contexte de l’application (avec l’espace de noms MVC mappé sur mvc :

     

J’ai résolu le problème en proposant du contenu statique via le servlet «default», qui sert simplement le contenu au client. Donc, mon web.xml ressemble à ceci:

  MyApp org.springframework.web.servlet.DispatcherServlet   MyApp /    default *.css   default *.js   default *.jpg   

J’espère que cela t’aides.

Le moyen le plus simple pour moi (si vous utilisez une version assez tardive de Spring) est

   ... 

Une façon de le faire serait avec les filtres. Vous devriez écrire un peu de code personnalisé, mais ce n’est pas mauvais. Voici un exemple si vous ne souhaitez pas transmettre les fichiers * .css ou * .js à votre servlet Spring:

web.xml:

  fileTypeFilter foo.FileTypeFilter /*  

Classe Java:

 public class FileTypeFilter implements Filter { public void init(FilterConfig conf) { // init logic here } public void destroy() { // release resources here } public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException { if(shouldExclude(req)) { chain.doFilter(req, res); //some logic so the request doesnt go to the servlet //maybe you could just forward //the request directly to the file getting accessed. not sure if that would work } //file should be passed to the servlet; you can do some logic here //if you want } private boolean shouldExclude(ServletRequest req) { if(req instanceof HttpServletRequest) { HttpServletRequest hreq = (HttpServletRequest) req; return (hreq.getRequestURI().endsWith(".css") || hreq.getRequestURI().endsWith(".js")); } return false; } } 

Je n’ai pas testé cela, mais je pense que ça va marcher.

EDIT : Il n’y a pas de fonctionnalité d’exclusion dans la spécification de servlet. Je ne pense pas qu’il y ait un bon moyen de le faire au spring, mais cela permet essentiellement d’obtenir la même chose dans votre message.

EDIT 2 : Si vous voulez pouvoir changer facilement ce qui est filtré, vous pouvez simplement utiliser Spring pour injecter quelque chose dans le filtre à l’exécution.

EDIT 3 : Je viens de me rendre compte que si vous transmettez directement au fichier, le filtre recommencera et vous serez pris dans une boucle infinie. Il pourrait y avoir une autre façon de faire cela avec des filtres, mais honnêtement, je ne suis pas sûr de ce que c’est.

Qu’est-ce que vous utilisez pour servir vos images statiques? Si c’est Apache, vous pouvez configurer Apache pour ne pas transmettre les requêtes css / js à votre serveur d’applications.

Si vous utilisez Tomcat, vous devriez mettre quelque chose comme ceci dans votre httpd.conf:

 JkUnMount /*.css webapp 

Où ‘webapp’ est l’entrée de vos workers.properties.

Désolé je ne peux pas vous donner une solution Spring pure, mais c’est comme ça que je le fais.

J’ai le même problème et voici comment je l’ai résolu:

Ce qui suit a été ajouté au fichier web.xml:

  default *.js *.css *.ico *.png *.jpg *.htc *.gif *.html *.htm  

Les éléments suivants ont été ajoutés au fichier de définition du bean de servlet MVC de spring3 (tel que applicationContext.xml, le fichier configuré dans web.xml en tant que contextConfigLocation):

   

Avez-vous une ou plusieurs extensions cohérentes pour les requêtes que vous souhaitez traiter par le répartiteur Spring (je crois que la plupart des exemples Spring utilisent un * .htm)? Dans ce cas, vous pouvez mapper les extensions que vous souhaitez traiter, ce qui contournerait vos fichiers css et js.

Sinon, je suis d’accord avec Nalandial, l’approche Filter est probablement la meilleure solution à ce stade.

Généralement, les grands sites Web préfèrent utiliser un autre serveur uniquement pour gérer le contenu statique. Les demandes de contenu statique vont à un serveur et la dynamic à un autre (avec Spring, dans ce cas).

Dans de nombreux cas, le serveur Nginx (http://nginx.com/), un serveur récent et très rapide.

Mais ce n’est pas sortingvial à faire. Beaucoup de configurations

J’utilise un chemin d’URL virtuel pour récupérer la ressource dont j’ai besoin. Généralement, j’utilise Spring MVC, donc je ne pouvais pas avoir javascripts et css sous le dossier / WEB-INF / views. J’ai conçu ce servlet personnalisé pour autoriser UNIQUEMENT l’access aux fichiers .js et .css dans le dossier / WEB-INF / views. Dans votre cas, si vous déplacez le dossier / css et / js vers un dossier parent tel que / resource, ma solution vous sera applicable.

Vous pouvez changer l’URL Ssortingng = “YOUR_RESOURCE_FOLDER”

Ainsi, par exemple, le chemin virtuel peut être quelque chose comme http://www.mysite.com/resources/path/path/app.js

Cela correspondra à mon /WEB-INF/views/path/path/app.js

web.xml

  ResourceDispatcherServlet mywebapp.web.ResourceDispatcherServlet   ResourceDispatcherServlet /resource/*  

servlet

 public class ResourceDispatcherServlet extends HttpServlet { public void init() throws ServletException { } public void doGet(HttpServletRequest req, HttpServletResponse rsp) throws ServletException, IOException { Ssortingng servletPath = req.getServletPath(); // /resource Ssortingng pathInfo = req.getPathInfo(); // /path/path/app.js Ssortingng url = "/WEB-INF/views" + pathInfo; Ssortingng lastPath = SsortingngUtil.subssortingngAfterLast(pathInfo, "/"); Ssortingng extension = SsortingngUtil.subssortingngAfterLast(lastPath, "."); try { RequestDispatcher dispatcher = null; if (!SsortingngUtil.isEmpty(extension) && ("js".equals(extension) || "css".equals(extension))) { dispatcher = req.getRequestDispatcher(url); } if (dispatcher != null) { dispatcher.include(req, rsp); } else { rsp.sendError(404); } } catch (Exception e) { if (!rsp.isCommitted()) { rsp.sendError(500); } } } } 

Si vous utilisez Spring 3.0.4 et supérieur, vous devez utiliser la solution fournie par atrain

Sinon, vous pouvez faire cette chose simple :

peut-être vous avez la structure de répertoire statique que vous voulez servir:

 WebContent | WEB-INF | public | css | js | img 

Les projets Web dynamics Eclipse génèrent par défaut la structure suivante: WebContent/WEB-INF . Déplacez le dossier public de votre répertoire WEB-INF dans le répertoire WebContent .

Côté client

référez vos fichiers statiques de la manière suivante:

  

Voici ma référence

Il est plus propre d’utiliser UrlRewriteFilter pour redirect la requête vers votre servlet, en voici un exemple: urlrewrite.xml

   ^/img/(.*)$ /img/$1   ^/js/(.*)$ /js/$1   ^/css/(.*)$ /css/$1   ^/(.*)$ /app/$1   /app/(.*)$ /$1   

REMARQUES:

  • Il est important que la dernière soit en bas, donc img, js, css seront pris en premier
  • La est facultative et sert uniquement à rendre l’existant
    render /some au lieu de /app/some

Dans mon cas, tout allait bien. Mais j’ai un problème dans un contrôleur

c’était mon problème @RequestMapping (method = RequestMethod.GET)

y change pour cela:

 @RequestMapping(value = "/usuario", method = RequestMethod.GET) 

et il fonctionne

recherchez un contrôleur qui a mauvaise @RequestMappgin et changez.