Excluding Content from url-pattern in Java web.xml

A while ago I blogged about my frustration with my inability to exclude certain URLs from a url-pattern mapping. In short, I wanted to map everything except /static/* to a dispatch servlet.

There is a way to do this, in some servlet servers. Many (most, all?) servlet containers define a default servlet to handle static content. Be default, any unmapped URLs will be handled by the default servlet. However, you can explicitly map certain URLs to this default servlet, achieving a de-facto url-exclude pattern.

Here is an example:
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/static/*</url-pattern>
</servlet-mapping>

<servlet-mapping>
<servlet-name>SpringMVCServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
Where in this case, you have SpringMVCServlet defined in your web.xml, but not default. The default servlet definition is inherited from the servlet container.

The order shouldn't matter, as long as your mapping for the default servlet is more specific.

This is known to work in at least Jetty and Tomcat.

4 comments:

  1. Lookslike this can be done by means of Struts2: http://struts.apache.org/2.2.1/docs/static-content.html

    ReplyDelete
  2. Yikes. When I do this in Tomcat, it makes my entire WEB-INF directory public. A pretty nasty side-effect. For instance, i can access a JSP by doing something like http://localhost/webapp/static/WEB-INF/jsp/index.jsp.

    ReplyDelete
  3. I found the solution to this problem of /* url-pattern at
    http://java-espresso.in/2011/09/webxml-problem-and-solution-for-url.html.

    They have given two approaches to solve this problem..

    ReplyDelete
  4. Your idea seems very interesting... Going to try it out.
    The comment from Mike about WEB-INF becoming public is a bit scary though... Can anyone confirm whether that is in fact happening?

    ReplyDelete