Affects: 5.2.9 (possibly earlier)
We are building a REST application with Spring Boot.
Because we have several endpoints that behave similarly (but with different parameters), we build several child contexts, each with one DispatcherServlet
, under different urlMappings
(for example, /fish/*
and /cat/*
with one @RequestMapping
/feed
each). Until some versions ago, this worked fine.
With the update to 5.2.9, however, these endpoints return 404
errors. Debugging seems to hint that the RequestMapping
is not found because the request contains the path fish/feed
while the RequestMappingHandlerMapping
only knows about /feed
. (According to our debuggin, the UrlPathHelper
has alwaysUseFullPath
set to true
. We don't know why or how.)
We register the DispatcherServlet
like this:
val dispatcherServlet = DispatcherServlet()
dispatcherServlet.setApplicationContext(applicationContext)
return ServletRegistrationBean(
dispatcherServlet,
"/<cat|fish>/*"
)
What do we need to set so that the original mapping works again? We have not found anything in the documentation or the changelogs that seems to impact the mapping.
Comment From: jhoeller
@rstoyanchev, could this be related to spring-projects/spring-framework#25864 in the sense of another side effect of our 5.2.9 revision there?
Comment From: rstoyanchev
I think this is a duplicate of https://github.com/spring-projects/spring-boot/issues/22682 although it's not clear why you're seeing that with 5.2.9 which presumably means Spring Boot 2.3.4. In any case I don't think it's a change in the Spring Framework that leads to this.
Can you clarify the version of Spring Boot? If you try to vary independently the Spring Framework and Spring Boot versions does that show which version change demonstrates the issue?
Comment From: bienenstich
The Spring Boot version is 2.3.4, we are going to try varying the versions independently and get back to you.
Comment From: fdw
We tested Spring Boot 2.3.4 and 2.3.0 with Spring Framework 5.2.9. The result is that the older Spring Boot version works, whereas the new one doesn't. It seems that this is not a regression in Spring Framework (as far as I understand this).
Should we open an issue in Spring Boot?
Comment From: bclozel
@fdw Could you create a sample project reproducing the problem? I'm transferring this issue to the Spring Boot tracker.
Comment From: bienenstich
We built you a minimal sample project that reproduces the behavior described above. To test, please follow the instructions in the README.md
file provided here
Comment From: bclozel
Rossen was right, this is indeed a duplicate of #22682 and I'm closing this issue as a result.
As of #21499, Spring Boot auto-configures the UrlPathHelper
to use the full path, as recommended by the Spring Framework team. This is done only if there's a single DispatcherServlet
instance mapped to "/"
(as fixed in #22682).
The problem here is that the unusual setup of your sample application prevents the Spring Boot parent context from detecting the additional DispatcherServlet
at the right time.
I'm sure there are valid reasons to use this setup, so the simplest way to fix that is to customize the UrlPathHelper
yourself like this:
@Configuration
class WebConfig : WebMvcConfigurer {
override fun configurePathMatch(configurer: PathMatchConfigurer) {
val urlPathHelper = UrlPathHelper()
urlPathHelper.setAlwaysUseFullPath(false)
configurer.setUrlPathHelper(urlPathHelper)
}
}
Another way would be to simplify your current setup by:
- avoiding to enable Spring MVC (and opt-out from the auto-configuration by adding
@EnableWebMvc
) - follow the guidelines for parent/child context setups (see the How-to section and SpringApplicationBuilder fluent builder section in the reference documentation).
Thanks!
Comment From: fdw
First off, thank you very much for your answer and your help! It's actually been a pleasure 🙂
Secondly, one of the reasons for our unusual setup is that we don't know how many/which child contexts we need: We read a list from a property (using Spring's mechanisms) and create them accordingly. If we understand the docs right, this wouldn't be possible when we use the SpringApplicationBuilder
, right?
Do you have any hints for us how we might solve that?
Comment From: bclozel
I see, in this case I don't know how to solve that particular problem with an unknown number of child contexts. I don't think the SpringApplicationBuilder
approach would work there, you're right.
Comment From: fdw
Pity, but thanks again for your time and help!