Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ambiguous mapping found when using class multi level @RequestMapping urls

Tags:

spring-mvc

I'm getting the following exception if I use multi level urls in class like @RequestMapping("/api/v0.1"):

java.lang.IllegalStateException: Ambiguous mapping found. Cannot map 'userController'
bean method getUsers()|to {[/api/v0.1]}: There is already 'userController' bean
method getUser(java.lang.String) mapped.

It's like the method level mappings doesn't get into consideration at all.
But it's ok if I put @RequestMapping("/api") i.e. remove the /v0.1 part.

Here is the configuration stripped up to the minimal case:

@Controller
@RequestMapping("/api/v0.1")
public class UserController {   

    @RequestMapping(value = "/users")
    @ResponseBody
    public List<User> getUsers() {
        return null;
    }

    @RequestMapping(value = "/users/{username}")
    @ResponseBody
    public User getUser(@PathVariable String username) {
        return null;
    }
}

web.xml

<servlet-mapping>
    <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

servlet-context.xml:

<!-- Configures the @Controller programming model -->
<mvc:annotation-driven />

<!-- Forwards requests to the "/" resource to the "welcome" view -->
<mvc:view-controller path="/" view-name="home"/>    

<!-- Handles HTTP GET requests for /assets/** by efficiently serving up static resources in the ${webappRoot}/resources/ directory -->
<mvc:resources mapping="/assets/**" location="/assets/" />

I'm using spring 3.1. I also tried to set alwaysUseFullPath property to true of the RequestMappingHandlerMapping bean but it didn't change the situation.

like image 693
SelimOber Avatar asked Nov 04 '22 20:11

SelimOber


1 Answers

Very interesting issue - I checked what could be going on, you are right the "v0.1" is really throwing off the org.springframework.util.AntPathMatcher which creates the full URI path by combining the path from the controller and the path from the mapped method. If it sees a "file.extension" kind of a pattern in the Controller, then it totally ignores the path mapping of the method - this is the reason why your @PathVariable was getting ignored.

I am not sure if this is a bug or intended behavior in Spring MVC, temporary fix would be along what you have already mentioned -

1.To remove "v0.1" from the RequestMapping of Controller and make it without extension say v0_1

2.To put this mapping in the mapped method:

@Controller
@RequestMapping("/api")
public class UserController {   

    @RequestMapping(value = "/v0.1/users")
    @ResponseBody
    public List<User> getUsers() {
        return null;
    }

    @RequestMapping(value = "/v0.1/users/{username}")
    @ResponseBody
    public User getUser(@PathVariable String username) {
        return null;
    }
}
like image 85
Biju Kunjummen Avatar answered Nov 09 '22 05:11

Biju Kunjummen