it-swarm.com.de

Kann SpringMVC so konfiguriert werden, dass alle Anforderungen verarbeitet werden, statische Inhaltsverzeichnisse jedoch ausgeschlossen werden?

Wenn ich meine Spring-Anwendung zur Verarbeitung aller eingehenden Anforderungen ('/ *') zuordnen, geben die Anfragen nach statischem Inhalt 404 zurück. Eine Anforderung für "myhost.com/css/global.css" würde beispielsweise 404 zurückgeben, auch wenn die Ressource vorhanden ist, da Spring die Anforderung abfängt.

Die Alternative besteht darin, SpringMVC einem Unterverzeichnis (z. B. '/ home /') zuzuordnen. In diesem Fall müssen Sie dieses Verzeichnis jedoch in allen Links innerhalb der Anwendung übergeben. Gibt es eine Möglichkeit, SpringMVC auf '/ ' zuzuordnen und eine Reihe von Verzeichnissen von der Verarbeitung auszuschließen?

Meine aktuelle web.xml-Konfiguration lautet:

<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>

Idealerweise hätte ich gerne, dass das Mapping ungefähr so ​​aussieht:

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

Ist so etwas möglich?

58
Rich Kroll

Wenn Sie dies nur mit Spring machen möchten, ist es möglich, aber etwas unordentlich:

  1. Sie müssen entweder ein SimpleUrlHandlerMapping verwenden, für das Sie explizit URL-Muster angeben können, die den Controllern OR zugeordnet werden sollen, um es so zu erweitern, dass "ignorierte" URLs wie "css/**" unterstützt werden.
  2. Sie müssen Ihre eigene HttpRequestHandler - Implementierung schreiben, die im Wesentlichen aus "getServletContext (). GetRequestDsipatcher (). Include ()" besteht, um die angeforderte Ressource so zurückzugeben, wie sie ist.
  3. Sie müssen diesen Handler als defaultHandler für das obige SimpleUrlHandlerMapping registrieren.

Sobald dies erledigt ist, werden alle Anforderungen, die nicht Ihren Controllern zugeordnet werden können, an Ihre HttpRequestHandler weitergeleitet und "wie besehen" bedient.

7
ChssPly76

HINWEIS: Diese Antwort gilt NUR für Spring 3.0.4+.

(Übrigens, diese Frage wurde auch hier behandelt: Spring liefert statischen Inhalt mit mvc: resources, ungültiges xsd )

Schauen Sie sich das Spring mvc-showcase-Projekt im Spring Subversion-Repository an. Es zeigt genau, was Sie tun möchten, nämlich, dass Sie statische Ressourcen definieren können, die nicht vom DisapatcherServlet verarbeitet werden. Siehe Datei /mvc-showcase/src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml. Hier ein Auszug aus dem Umgang mit diesen Ausschlüssen. JS, CSS und Bilder befinden sich im App-Kontextstammverzeichnis (der MVC-Namespace ist mvc zugeordnet.)

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

Ich habe das Problem gelöst, indem statischer Inhalt über das "Standard" -Servlet bereitgestellt wurde, das den Inhalt nur für den Client bereitstellt. So sieht meine web.xml so aus:

<servlet>
    <servlet-name>MyApp</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>MyApp</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping> <!-- The 'dynamic' content -->

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.css</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.js</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.jpg</url-pattern>
</servlet-mapping> <!-- The 'static' content -->

Hoffe das hilft.

27
user153415

Am einfachsten ist es für mich (wenn man eine spät genug Version von Spring verwendet)

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

Eine Möglichkeit wäre es mit Filtern. Sie müssen ein wenig benutzerdefinierten Code schreiben, aber das ist nicht schlecht. Hier ein Beispiel, wenn Sie * .css- oder * .js-Dateien nicht an Ihr Spring-Servlet übergeben möchten:

web.xml:

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

Java-Klasse:

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;
    }
}

Ich habe das nicht getestet, aber ich denke, es wird funktionieren.

EDIT: Die Servlet-Spezifikation enthält keine Ausschlussfunktion. Ich denke nicht, dass es eine gute Möglichkeit gibt, dies innerhalb des Frühlings zu tun, aber im Wesentlichen wird in Ihrem Beitrag dasselbe erreicht.

EDIT 2 : Wenn Sie einfach ändern möchten, was gefiltert wird, können Sie Spring verwenden, um zur Laufzeit etwas in den Filter einzufügen. 

EDIT 3 : Ich habe gerade festgestellt, wenn Sie direkt zur Datei weiterleiten, wird der Filter erneut ausgeführt, und Sie werden in einer Endlosschleife gefangen. Es gibt möglicherweise eine andere Möglichkeit, dies mit Filtern zu tun, aber ich bin ehrlich nicht sicher, was es ist.

3
Alex Beardsley

Ich habe das gleiche Problem und hier ist, wie ich es gelöst habe:

Folgendes wurde der Datei web.xml hinzugefügt:

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.js</url-pattern>
    <url-pattern>*.css</url-pattern>
    <url-pattern>*.ico</url-pattern>
    <url-pattern>*.png</url-pattern>
    <url-pattern>*.jpg</url-pattern>
    <url-pattern>*.htc</url-pattern>
    <url-pattern>*.gif</url-pattern>
    <url-pattern>*.html</url-pattern>
    <url-pattern>*.htm</url-pattern>
</servlet-mapping>

Der Spring3-MVC-Servlet-Bean-Definitionsdatei wurde Folgendes hinzugefügt (z. B. applicationContext.xml, die Datei, die in web.xml als contextConfigLocation konfiguriert ist):

<mvc:annotation-driven /> 
<mvc:default-servlet-handler />
2
Green Lei

Was verwenden Sie zum Bereitstellen Ihrer statischen Bilder? Wenn es sich um Apache handelt, können Sie Apache so konfigurieren, dass keine css/js-Anforderungen an Ihren App-Server weitergeleitet werden.

Wenn Sie Tomcat verwenden, fügen Sie so etwas in Ihre httpd.conf ein:

JkUnMount /*.css  webapp

Wo "webapp" ist der Eintrag von Ihren Arbeitern.Eigenschaft.

Es tut mir leid, dass ich Ihnen keine reine Frühlingslösung geben kann, aber so mache ich es.

2
Darren Greaves

Haben Sie eine konsistente Erweiterung für die Anforderungen, die Sie vom Spring-Dispatcher bearbeiten möchten (ich glaube, die meisten Spring-Beispiele verwenden ein * .htm)? In diesem Fall können Sie die Erweiterungen zuordnen, die Sie verarbeitet haben möchten, wodurch Ihre CSS- und JS-Dateien umgangen werden.

Ansonsten würde ich Nalandial zustimmen, der Filter-Ansatz ist an diesem Punkt wahrscheinlich die beste Lösung.

0
jridley

Ich verwende den virtuellen URL-Pfad, um die benötigte Ressource abzurufen. Normalerweise verwende ich Spring MVC, daher konnte ich keine javascripts und css unter dem Ordner/WEB-INF/views haben. Ich habe mir dieses benutzerdefinierte Servlet ausgedacht, um NUR den Zugriff auf .js- und .css-Dateien im Ordner/WEB-INF/views zuzulassen. Wenn Sie in Ihrem Fall den Ordner/css und/js in einen übergeordneten Ordner wie/resource verschieben, ist meine Lösung für Sie relevant.

Sie können den String url = "YOUR_RESOURCE_FOLDER" ändern.

Der virtuelle Pfad kann zum Beispiel so aussehen wie http://www.mysite.com/resources/path/path/app.js

Das wird meinem /WEB-INF/views/path/path/app.js zugeordnet

web.xml

<servlet>
    <servlet-name>ResourceDispatcherServlet</servlet-name>
    <servlet-class>mywebapp.web.ResourceDispatcherServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>ResourceDispatcherServlet</servlet-name>
    <url-pattern>/resource/*</url-pattern>
</servlet-mapping>

servlet

public class ResourceDispatcherServlet extends HttpServlet {

    public void init() throws ServletException {

    }

    public void doGet(HttpServletRequest req, HttpServletResponse rsp) throws ServletException, IOException {


        String servletPath = req.getServletPath();   // /resource
        String pathInfo = req.getPathInfo();         // /path/path/app.js

        String url = "/WEB-INF/views" + pathInfo;

        String lastPath = StringUtil.substringAfterLast(pathInfo, "/");
        String extension = StringUtil.substringAfterLast(lastPath, ".");

        try {
            RequestDispatcher dispatcher = null;
            if (!StringUtil.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);
            }
        }
    }
}
0
webpro2828

In meinem Fall war alles in Ordnung. Aber ich habe ein Problem in einem Controller

das war mein problem @RequestMapping (method = RequestMethod.GET)

ich ändere dafür:

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

und es funktioniert

suchen Sie nach einem Controller mit fehlerhaftem @RequestMappgin und ändern Sie ihn.

0
user3193801

Wenn Sie Spring 3.0.4 oder höher verwenden, sollten Sie von atrain bereitgestellte Lösung verwenden.

Andernfalls können Sie diese einfache Sache machen:

vielleicht haben Sie die folgende statische Verzeichnisstruktur, die Sie bedienen möchten:

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

Eclipse Dynamische Webprojekte generieren standardmäßig folgende Struktur: WebContent/WEB-INF. Verschieben Sie den Ordner public aus Ihrem WEB-INF-Verzeichnis in das Verzeichnis WebContent.

Auf Kundenseite

verweisen Sie Ihre statischen Dateien auf folgende Weise:

<link rel="stylesheet" type="text/css" href="public/css/mystyles.css">

Hier ist mein Verweis.

0
Vikram