How to handle static content in Spring MVC?

2018-12-31 05:37发布

I am developing a webapp using Spring MVC 3 and have the DispatcherServlet catching all requests to '/' like so (web.xml):

  <servlet>
    <servlet-name>app</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>app</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

Now this works as advertised, however how can I handle static content? Previously, before using RESTful URLs, I would have caught all *.html for example and sent that to the DispatcherServlet, but now it's a different ball game.

I have a /static/ folder which includes /styles/, /js/, /images/ etc and I would like to exclude /static/* from the DispatcherServlet.

Now I could get static resources working when I did this:

  <servlet-mapping>
    <servlet-name>app</servlet-name>
    <url-pattern>/app/</url-pattern>
  </servlet-mapping>

But I want it to have nice URLs (the point of me using Spring MVC 3) not the landing page being www.domain.com/app/

I also don't want a solution coupled to tomcat or any other servlet container, and because this is (relatively) low traffic I don't need a webserver (like apache httpd) infront.

Is there a clean solution to this?

标签: spring-mvc
22条回答
ら面具成の殇う
2楼-- · 2018-12-31 06:09

If I understand your issue correctly, I think I have found a solution to your problem:

I had the same issue where raw output was shown with no css styles, javascripts or jquery files found.

I just added mappings to the "default" servlet. The following was added to the web.xml file:

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

This should filter out the javascript and css file requests from the DispatcherRequest object.

Again, not sure if this is what you are after, but it worked for me. I think "default" is the name of the default servlet within JBoss. Not too sure what it is for other servers.

查看更多
零度萤火
3楼-- · 2018-12-31 06:09

There's another stack overflow post that has an excellent solution.

It doesn't seem to be Tomcat specific, is simple, and works great. I've tried a couple of the solutions in this post with spring mvc 3.1 but then had problems getting my dynamic content served.

In brief, it says add a servlet mapping like this:

<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/images/*</url-pattern>
</servlet-mapping>
查看更多
余欢
4楼-- · 2018-12-31 06:09

From Spring 3, all the resources needs to mapped in a different way. You need to use the tag to specify the location of the resources.

Example :

<mvc:resources mapping="/resources/**" location="/resources/" />

By doing this way, you are directing the dispatcher servlet to look into the directory resources to look for the static content.

查看更多
后来的你喜欢了谁
5楼-- · 2018-12-31 06:12

I found a way around it using tuckey's urlrewritefilter. Please feel free to give a better answer if you have one!

In web.xml:

<filter>
    <filter-name>UrlRewriteFilter</filter-name>
    <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>UrlRewriteFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

  <servlet>
    <servlet-name>app</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>app</servlet-name>
    <url-pattern>/app/*</url-pattern>
  </servlet-mapping>

In urlrewrite.xml:

<urlrewrite default-match-type="wildcard">
<rule>
    <from>/</from>
    <to>/app/</to>
</rule>
<rule match-type="regex">
    <from>^([^\.]+)$</from>
    <to>/app/$1</to>
</rule>
<outbound-rule>
    <from>/app/**</from>
    <to>/$1</to>
</outbound-rule>    

This means that any uri with a '.' in it (like style.css for example) won't be re-written.

查看更多
路过你的时光
6楼-- · 2018-12-31 06:14

I know there are a few configurations to use the static contents, but my solution is that I just create a bulk web-application folder within your tomcat. This "bulk webapp" is only serving all the static-contents without serving apps. This is pain-free and easy solution for serving static contents to your actual spring webapp.

For example, I'm using two webapp folders on my tomcat.

  1. springapp: it is running only spring web application without static-contents like imgs, js, or css. (dedicated for spring apps.)
  2. resources: it is serving only the static contents without JSP, servlet, or any sort of java web application. (dedicated for static-contents)

If I want to use javascript, I simply add the URI for my javascript file.

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

For static images, I'm using the same method.

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

Last, I put "security-constraint" on my tomcat to block the access to actual directory. I put "nobody" user-roll to the constraint so that the page generates "403 forbidden error" when people tried to access the static-contents path.

So far it works very well for me. I also noticed that many popular websites like Amazon, Twitter, and Facebook they are using different URI for serving static-contents. To find out this, just right click on any static content and check their URI.

查看更多
残风、尘缘若梦
7楼-- · 2018-12-31 06:16

My own experience with this problem is as follows. Most Spring-related web pages and books seem to suggest that the most appropriate syntax is the following.

    <mvc:resources mapping="/resources/**" location="/resources/" />

The above syntax suggests that you can place your static resources (CSS, JavaScript, images) in a folder named "resources" in the root of your application, i.e. /webapp/resources/.

However, in my experience (I am using Eclipse and the Tomcat plugin), the only approach that works is if you place your resources folder inside WEB_INF (or META-INF). So, the syntax I recommend is the following.

    <mvc:resources mapping="/resources/**" location="/WEB-INF/resources/" />

In your JSP (or similar) , reference the resource as follows.

<script type="text/javascript"
        src="resources/my-javascript.js">
</script>

Needless to mention, the entire question only arose because I wanted my Spring dispatcher servlet (front controller) to intercept everything, everything dynamic, that is. So I have the following in my web.xml.

<servlet>
    <servlet-name>front-controller</servlet-name>
    <servlet-class>
                org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <load-on-startup>1</load-on-startup>
    <!-- spring automatically discovers /WEB-INF/<servlet-name>-servlet.xml -->
</servlet>

<servlet-mapping>
    <servlet-name>front-controller</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

Finally, since I'm using current best practices, I have the following in my front controller servlet xml (see above).

<mvc:annotation-driven/>

And I have the following in my actual controller implementation, to ensure that I have a default method to handle all incoming requests.

@RequestMapping("/")

I hope this helps.

查看更多
登录 后发表回答