9

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?

1 Answer 1

15

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)

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks Anton, the only problem I face is that I have other servlets defined alongside the MVC dispatcher servlet (GWT stuff etc) so I don't want to route everything through it. I guess I'll need to look at some url-rewriting options
You can define a bunch of <url-pattern> in servlet declaration. In your scenario, you can map Spring MVC to /rest and your controller to /users
@Anton What do you mean by "map Spring MVC to /rest"? You mean the dispatcher servlet? His controller looks like it uses Spring MVC so I'm a bit confused on your distinction. I've got a similar issue myself.
@TobyHobson I prefer to serve GWT from /app/rpc/* and /app/int/rpc/* where int are internal (post login) RPC's that can easily be fenced off with a Spring Security URL rule.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.