From 8760006c72bfe2f28ff05e9a316eef170088163e Mon Sep 17 00:00:00 2001 From: Anton Platonov Date: Mon, 27 Dec 2021 15:38:33 +0200 Subject: [PATCH] fix(Fusion): Spring MVC string patterns request mapping compatibility Fixes #12623 With Spring Boot 2.6, PathPattern matching is a default, however with 2.4 / 2.5 Spring MVC still uses string-based pattern matching for paths. This fixes compatibility with string-based pattern mapping mode when prepending the endpoint path prefix. --- .../fusion/FusionControllerConfiguration.java | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/fusion-endpoint/src/main/java/com/vaadin/fusion/FusionControllerConfiguration.java b/fusion-endpoint/src/main/java/com/vaadin/fusion/FusionControllerConfiguration.java index 96383fd0d48..0cdc3cf8669 100644 --- a/fusion-endpoint/src/main/java/com/vaadin/fusion/FusionControllerConfiguration.java +++ b/fusion-endpoint/src/main/java/com/vaadin/fusion/FusionControllerConfiguration.java @@ -25,6 +25,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; +import org.springframework.web.util.pattern.PathPatternParser; import com.vaadin.flow.server.auth.AccessAnnotationChecker; import com.vaadin.fusion.auth.CsrfChecker; @@ -95,9 +96,27 @@ protected void registerHandlerMethod(Object handler, */ private RequestMappingInfo prependEndpointPrefixUrl( RequestMappingInfo mapping) { - return mapping.mutate() - .paths(fusionEndpointProperties.getVaadinEndpointPrefix()) - .build().combine(mapping); + RequestMappingInfo.Builder prefixMappingBuilder = RequestMappingInfo.paths( + fusionEndpointProperties.getVaadinEndpointPrefix()); + if (mapping.getPatternsCondition() == null) { + // `getPatternsCondition()` and `getPathPatternsCondition()` are + // mutually exclusive: only one of them is active, the other + // returns null. Since patterns condition is null here, let us + // assume `mapping` uses parsed PathPatterns condition (default + // since Spring MVC 5.3). + // + // However, `prefixMappingBuilder` uses non-parsed patterns + // condition by default, which does not combine with parsed + // PathPatterns condition in `RequestMappingInfo.combine()`. + // + // Set the pattern parser option for `prefixMappingBuilder` + // to make it use parsed PathPatterns condition, so that + // `.combine(mapping)` below works. + RequestMappingInfo.BuilderConfiguration options = new RequestMappingInfo.BuilderConfiguration(); + options.setPatternParser(PathPatternParser.defaultInstance); + prefixMappingBuilder.options(options); + } + return prefixMappingBuilder.build().combine(mapping); } /**