2
votes

I'm trying to map a request to static resources in a spring environment. My app server is Jetty.

In web.xml, I'm mapping various url patterns to my spring servlet:

<servlet-mapping>
    <servlet-name>spring</servlet-name>
    <url-pattern>/static/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>spring</servlet-name>
    <url-pattern>/otherpath/*</url-pattern>
</servlet-mapping>
[many more mappings...]

Note that "/" is not mapped to my spring servlet.

In spring-servlet.xml, I'm using the mvc:resources tag to map a url to a directory with my static content:

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

This does not work as I expected. Instead of mapping

/static/ to /WEB-INF/static/,

it maps

/static/static/ to /WEB-INF/static

The reason is that the mapping given in "mvc:resources" seems to not be relative to / but relative to the path that maps to the spring servlet.

Is there a way to consider the full path, relative to / for the mapping, not the path relative to the servlet mapping?

3
Don't know. But why not simply use /** instead of /static/** as mapping?JB Nizet
That would then be a catch-all mapping also for /otherpath/Twilite
And couldn't you have two different spring servlets: one for /otherpath/, and one for /static/?JB Nizet
A separate servlet just for the static stuff? That might work.Twilite

3 Answers

8
votes

The solution is to not use the mvc:resources tag, but to configure the corresponding handler with a bean and a URLHandlerMapping:

<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="alwaysUseFullPath" value="true"/>
    <property name="mappings">
        <props>
            <prop key="/static/*">staticResources</prop>
        </props>
    </property>
</bean>

<bean id="staticResources" class="org.springframework.web.servlet.resource.ResourceHttpRequestHandler">
    <property name="locations">
        <list>
            <value>/WEB-INF/static/</value>
        </list>
    </property>
</bean>

The SimpleUrlHandlerMapping with its alwaysUseFullPath property does allow more fine-grained control over the mapping.

0
votes

To answer your question with one short word. No, at least I don't think so.

The servlet looks inside it's own "space" and that is after the servlet-mapping done in web.xml. That in turn is after the mapping done i your container (like tomcat)

Would it be possible to add just one servlet to / and then add two <mvc:resource />? One with /static/** and one with /otherpath/** (or whatever you need there). If not I would go with JB Nizet's solution to add two different servlets entirely.

0
votes

Or you could use <mvc:default-servlet-handler/> and <spring:url>. It worked for me. mvc:resources doesn't seem to work when application is not started on the ROOT context.

Here's the configuration that I used (note the commented bit that was doing the resource mapping to the application started under 'localhost:8080/myapp' context, though context name shouldn't be in the spring config):

<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources -->
<!--<mvc:resources location="/styles" mapping="/myapp/styles/**"/>-->
<!--<mvc:resources location="/js" mapping="/myapp/js/**"/>-->

<!-- Allows for mapping the DispatcherServlet to "/" by forwarding static resource 
requests to the container's default Servlet -->
<mvc:default-servlet-handler/>

The trick is to use spring:url to resolve your application context. Here is what I used for that:

<spring:url value="/styles/site.css" var="site_style"/>
<link rel="stylesheet" href="${site_style}" type="text/css" media="screen"/>

I'm basically using relative paths to my root app folder, while spring takes care of adding the /myapp in front of it.

It's still pretty strange that mvc:resources doesn't do that on it's own, but at least this works and its still pretty neat.