Reputation: 198
We have a problem with two spring controllers that happen to interfere with each other. One controller matches via a wildcard-prefix to the URL suffix. Another controller matches to a URL prefix. I expect URLs to be read from left to right, which seems not to be the case.
Consider the following code (edited):
@RequestMapping(value = "/**/abcdefg")
public class Controller1 {...}
@RequestMapping(value = "/**/xyz")
public class Controller2 {...}
@RequestMapping(value = "/some/{path}")
public class Controller3
{
@RequestMapping(value = "/{page}", method = RequestMethod.GET)
public String page(@PathVariable("page") final String page, final Model model)
{ //do sth }
}
The Problem is now, that if the URL "/some/path/abcdefg" is called, the Controller1 kicks in. But I want Controller3.
Unfortunately this behavior is not the same with other controllers!
If the URL "/some/path/xyz" is called, Controller3 kicks in. This behavior is reproducable for the controllers. It always behaves the same and the controller is not randomly chosen.
The spring documentation as well as questions by other users point to the idea, that the "first" controller is taken, that matches the given pattern. However, this does not make quite sense to me, since Controller1 and 2 have a very similar requestmapping and yet the controllers match differently!
Everything is handled by the dispatcher servlet.
Does anyone have a hint what may be happening?
Upvotes: 3
Views: 4464
Reputation: 28529
This part I expect URLs to be read from left to right, which seems not to be the case. and you're right, its not the case. The mappings are resolved by specificity, the relevant piece of doc is available here
A pattern with a lower count of URI variables and wild cards is considered more specific. For example
/hotels/{hotel}/*
has 1 URI variable and 1 wild card and is considered more specific than/hotels/{hotel}/**
which as 1 URI variable and 2 wild cards.If two patterns have the same count, the one that is longer is considered more specific. For example
/foo/bar*
is longer and considered more specific than/foo/*
.When two patterns have the same count and length, the pattern with fewer wild cards is considered more specific. For example
/hotels/{hotel}
is more specific than/hotels/*
.
If the two mappings match a request, a more specific will apply. Work out your mappings to follow the specificity rules, based on what are your requirements
Upvotes: 7