Java – Spring MVC @RequestMapping not working

javaspring-mvc

I have a strange scenario in which my controller is not invoked unless I map the dispatcher servlet to /* in web.xml. I have defined a controller with a RequestMapping:

@Controller  
public class UserController {

    @RequestMapping(value = "/rest/users", method = RequestMethod.GET)
    public ModelAndView getUsers(HttpServletRequest request) throws RestException {
      ...
    }  
}

And an application context:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">

    <context:component-scan base-package="com.test.rest.controller" /> 

Finally this is mapped in web.xml:

<servlet>
    <servlet-name>rest-servlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/restContext.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

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

This works as expected i.e. I can make requests to /rest/users. However if I change the web.xml mapping to:

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

I get an MVC error:

WARN servlet.PageNotFound: No mapping found for HTTP request with URI
[/rest/users] in DispatcherServlet with name 'rest-servlet'.

It seems really strange because the error indicates that the request is being mapped to the dispatcher-servlet, yet the only thing that has changed is the servlet mapping.

Has anyone else encountered this?

Best Answer

Dispatcher servlet is the main servlet of Spring MVC. It handle all request, coming to your application, and using its own routing engine dispatch it to Controllers. If you change it to

 <url-pattern>/rest/*</url-pattern>

Then your request should be like this rest/rest/users

The common pattern - allow dispatch servlet to handle all incoming request (first configuration is valid)

Related Topic