Jabbering Giraffe

Mapping a servlet to /

An interesting problem cropped up today. We want to use a servlet for the home page in a Spring Web MVC project. Initially we had this in web.xml.

  <servlet>
    <servlet-name>foo</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>foo</servlet-name>
    <url-pattern>*.html</url-pattern>
  </servlet-mapping>

Now, we want to add in a handler specifically for /. How to do that? A bit of googling turned up this method.

  <servlet>
    <servlet-name>foo</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>foo</servlet-name>
    <url-pattern>*.html</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>foo</servlet-name>
    <url-pattern>/home</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <welcome-file>home</welcome-file>
  </welcome-file-list>

I’m not 100% sure why this works—the rules for mapping URLs to servlets are a little confusing to me. But it certainly seems to handle the situation correctly. My initial attempts to get this working managed to break everything by handling everything through the DispatcherServlet, even things like CSS. That was unacceptable.

Aha. Looking in the servlet spec shows why:

Web Application developers can define an ordered list of partial URIs called
welcome files in the Web application deployment descriptor.

I had thought that they were files, not URIs. That explains why it works nicely.

Of course, the solution above will attempt to look for “…/home” in any directory, even though I’ve only set it up to work for the root URL. I don’t think that’s much of a problem though.