59 votes

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

Si j'ai ma carte de printemps de l'application pour traiter toutes les demandes entrantes ('/*'), puis les demandes de contenu statique retour 404. Par exemple, une demande d' "myhost.com/css/global.css" renvoie une erreur 404, même si la ressource existe, comme le Printemps intercepte la demande.

L'alternative est de carte spring mvc dans un sous-répertoire (par exemple " /home/"), mais dans ce cas, vous devez passer cet annuaire dans tous les liens au sein de l'application. Est-il un moyen de la carte spring mvc '/' et d'exclure un ensemble de répertoires à partir de la transformation?

Mon actuel web.xml la configuration est:

<servlet>
    <servlet-name>springApp</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>2</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>springApp</servlet-name>
    <url-pattern>/home/*</url-pattern>
</servlet-mapping>

Idéalement, je voudrais avoir la cartographie être quelque chose comme ce qui suit:

 <servlet-mapping>
    <servlet-name>springApp</servlet-name>
    <url-pattern>/*</url-pattern>
    <exclude>/css/*,/js/*</exclude>
 </servlet-mapping>

C'est ce type de chose possible?

56voto

atrain Points 5653

NOTE: cette réponse s'applique à Ressort 3.0.4+ SEULEMENT

(BTW, cette question a également été abordée ici: Printemps servir du contenu statique avec mvc:les ressources, les invalides xsd)

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

<!-- resources exclusions from servlet mapping -->
<mvc:resources mapping="/css/**" location="/css/" />
<mvc:resources mapping="/images/**" location="/images/" />
<mvc:resources mapping="/js/**" location="/js/" />

8voto

ChssPly76 Points 53452

Si vous voulez faire cela avec le Printemps, la seule, c'est possible mais un peu en désordre:

  1. Vous devrez soit utiliser un SimpleUrlHandlerMapping pour lesquelles vous pouvez spécifier explicitement les formats d'URL qui doit être mappé les contrôleurs OU les étendre à l'appui "ignorer" les Url comme "css/**".
  2. Vous aurez besoin d'écrire votre propre HttpRequestHandler de mise en œuvre qui serait essentiellement composé de "getServletContext().getRequestDsipatcher().include()" appel de retour à la ressource demandée.
  3. Vous devez vous inscrire que gestionnaire comme defaultHandler pour le dessus de SimpleUrlHandlerMapping.

Une fois que tout cela est fait, toutes les demandes qui ne peut pas être mappé à vos contrôleurs seront transmis à votre HttpRequestHandler et servis "comme est".

4voto

Daniel Egan Points 196

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

 <mvc:resources mapping="/**/*.js" location="/"/>
<mvc:resources mapping="/**/*.css" location="/"/>
...
 

3voto

Alex Beardsley Points 4983

Une façon de le faire serait avec des Filtres. Vous devriez écrire un peu de code personnalisé, mais il n'est pas mauvais. Voici un exemple si vous ne voulez pas passer *.css ou *.js fichiers de votre Printemps servlet:

web.xml:

<filter-mapping>
    <filter-name>fileTypeFilter</filter-name>
    <filter-class>foo.FileTypeFilter</filter-class>
    <url-pattern>/*</url-pattern>
</filter-mapping>

La 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é, mais je pense que cela fonctionnera.

EDIT: Il n'est pas tout à exclure de la fonctionnalité dans la servlet spec. Je ne pense pas qu'il y est une bonne façon de le faire pendant le Printemps, mais essentiellement, il réalise la même chose dans votre post.

EDIT 2: Si vous voulez être en mesure de facilement changer ce qui est filtré, vous pouvez simplement utiliser le Printemps à injecter quelque chose dans le Filtre lors de l'exécution.

EDIT 3: je viens de réaliser que si vous transférez le fichier directement, il va faire le filtre de nouveau et que vous aurez pris dans une boucle infinie. Il y a peut être une autre façon de le faire avec des filtres, mais je suis franchement pas sûr de ce qu'il est.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X