1

I am confused with how Spring MVC's url-pattern mapping works.

When 'getServletMappings' returns "/",I can get the right response with "http://localhost:8080/hello".

but not working if i change it to "/app" and change url to "http://localhost:8080/app/hello", it returns 404 error.

Am I misunderstanding something, I also find that "/app/*" can work(i can understand this), but why cannot "/app"?

Please check my code:

public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected String[] getServletMappings() {
        // works with http://localhost:8080/hello
        return new String[] {
                "/"
        };
        // NOT working with http://localhost:8080/app/hello
        // return new String[] {
        //      "/app"
        //};
    }
}



@RestController
public class HTTPMethodsController {
   @RequestMapping("/hello")
   public String hello() {
       return "Hello SpringMVC.";
   }
}
guojiubo
  • 544
  • 1
  • 7
  • 15

1 Answers1

2

According to the Servlet specification Chapter 12.2, the mapping of servlets must use the following syntax:

  • A string beginning with a ‘/’ character and ending with a ‘/*’ suffix is used for path mapping.
  • A string beginning with a ‘*.’ prefix is used as an extension mapping.
  • The empty string ("") is a special URL pattern that exactly maps to the application's context root, i.e., requests of the form application's context root, i.e., requests of the form http://host:port//. In this case the path info is ’/’ and the servlet path and context path is empty string (““).
  • A string containing only the ’/’ character indicates the "default" servlet of the application. In this case the servlet path is the request URI minus the context path and the path info is null.
  • All other strings are used for exact matches only.

Therefore, mapping the DispatcherServlet with the URL "/app", causes the servlet container to route requests to it only when there is an exact match, meaning only if you change your url to "http://localhost:8080/app". That leaves no room for adding extra path to target specific Spring Controllers (to be more accurate: you could actually hit your hello() controller method if you mapped it with @RequestMapping("/app") because DispatcherServlet falls back to searching with the entire url, but practically that's not what you want).

So the mapping "/app/*" is correct, or you could also map it as the default servlet with "/" as you noticed.

Nazaret K.
  • 3,409
  • 6
  • 22
  • 31