[servlets] Difference between / and /* in servlet mapping url pattern

The familiar code:

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

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

My understanding is that /* maps to http://host:port/context/*.

How about /? It sure doesn't map to http://host:port/context root only. In fact, it will accept http://host:port/context/hello, but reject http://host:port/context/hello.jsp.

Can anyone explain how is http://host:port/context/hello mapped?

This question is related to servlets web.xml url-pattern

The answer is


Perhaps you need to know how urls are mapped too, since I suffered 404 for hours. There are two kinds of handlers handling requests. BeanNameUrlHandlerMapping and SimpleUrlHandlerMapping. When we defined a servlet-mapping, we are using SimpleUrlHandlerMapping. One thing we need to know is these two handlers share a common property called alwaysUseFullPath which defaults to false.

false here means Spring will not use the full path to mapp a url to a controller. What does it mean? It means when you define a servlet-mapping:

<servlet-mapping>
    <servlet-name>viewServlet</servlet-name>
    <url-pattern>/perfix/*</url-pattern>
</servlet-mapping>

the handler will actually use the * part to find the controller. For example, the following controller will face a 404 error when you request it using /perfix/api/feature/doSomething

@Controller()
@RequestMapping("/perfix/api/feature")
public class MyController {
    @RequestMapping(value = "/doSomething", method = RequestMethod.GET) 
    @ResponseBody
    public String doSomething(HttpServletRequest request) {
        ....
    }
}

It is a perfect match, right? But why 404. As mentioned before, default value of alwaysUseFullPath is false, which means in your request, only /api/feature/doSomething is used to find a corresponding Controller, but there is no Controller cares about that path. You need to either change your url to /perfix/perfix/api/feature/doSomething or remove perfix from MyController base @RequestingMapping.


I'd like to supplement BalusC's answer with the mapping rules and an example.

Mapping rules from Servlet 2.5 specification:

  1. Map exact URL
  2. Map wildcard paths
  3. Map extensions
  4. Map to the default servlet

In our example, there're three servlets. / is the default servlet installed by us. Tomcat installs two servlets to serve jsp and jspx. So to map http://host:port/context/hello

  1. No exact URL servlets installed, next.
  2. No wildcard paths servlets installed, next.
  3. Doesn't match any extensions, next.
  4. Map to the default servlet, return.

To map http://host:port/context/hello.jsp

  1. No exact URL servlets installed, next.
  2. No wildcard paths servlets installed, next.
  3. Found extension servlet, return.

I think Candy's answer is mostly correct. There is one small part I think otherwise.

To map host:port/context/hello.jsp

  1. No exact URL servlets installed, next.
  2. Found wildcard paths servlets, return.

I believe that why "/*" does not match host:port/context/hello because it treats "/hello" as a path instead of a file (since it does not have an extension).


The essential difference between /* and / is that a servlet with mapping /* will be selected before any servlet with an extension mapping (like *.html), while a servlet with mapping / will be selected only after extension mappings are considered (and will be used for any request which doesn't match anything else---it is the "default servlet").

In particular, a /* mapping will always be selected before a / mapping. Having either prevents any requests from reaching the container's own default servlet.

Either will be selected only after servlet mappings which are exact matches (like /foo/bar) and those which are path mappings longer than /* (like /foo/*). Note that the empty string mapping is an exact match for the context root (http://host:port/context/).

See Chapter 12 of the Java Servlet Specification, available in version 3.1 at http://download.oracle.com/otndocs/jcp/servlet-3_1-fr-eval-spec/index.html.