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:

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!