Skip to content

Commit a12a305

Browse files
committed
Optimize UrlPathHelper configuration for Spring MVC
Prior to this commit, Spring Boot would auto-configure Spring MVC and would keep the default `UrlPathHelper` configuration. Since Spring Boot is in charge of configuring the `DispatcherServlet` and its mapping, it is in a position to optimally configure the `UrlPathHelper` depending on the chosen mapping. This commit sets the `alwaysUseFullPath` property of `UrlPathHelper` if the Servlet mapping is `"/"`. This is more efficient since this configuration requires less processing of the request path. Closes gh-21499
1 parent 525e03d commit a12a305

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration.java

+14-1
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@
119119
import org.springframework.web.servlet.view.BeanNameViewResolver;
120120
import org.springframework.web.servlet.view.ContentNegotiatingViewResolver;
121121
import org.springframework.web.servlet.view.InternalResourceViewResolver;
122+
import org.springframework.web.util.UrlPathHelper;
122123

123124
/**
124125
* {@link EnableAutoConfiguration Auto-configuration} for {@link EnableWebMvc Web MVC}.
@@ -188,16 +189,20 @@ public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {
188189

189190
private final ObjectProvider<HttpMessageConverters> messageConvertersProvider;
190191

192+
private final ObjectProvider<DispatcherServletPath> dispatcherServletPath;
193+
191194
final ResourceHandlerRegistrationCustomizer resourceHandlerRegistrationCustomizer;
192195

193196
public WebMvcAutoConfigurationAdapter(ResourceProperties resourceProperties, WebMvcProperties mvcProperties,
194197
ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider,
195-
ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider) {
198+
ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider,
199+
ObjectProvider<DispatcherServletPath> dispatcherServletPath) {
196200
this.resourceProperties = resourceProperties;
197201
this.mvcProperties = mvcProperties;
198202
this.beanFactory = beanFactory;
199203
this.messageConvertersProvider = messageConvertersProvider;
200204
this.resourceHandlerRegistrationCustomizer = resourceHandlerRegistrationCustomizerProvider.getIfAvailable();
205+
this.dispatcherServletPath = dispatcherServletPath;
201206
}
202207

203208
@Override
@@ -227,6 +232,14 @@ public void configurePathMatch(PathMatchConfigurer configurer) {
227232
configurer.setUseSuffixPatternMatch(this.mvcProperties.getPathmatch().isUseSuffixPattern());
228233
configurer.setUseRegisteredSuffixPatternMatch(
229234
this.mvcProperties.getPathmatch().isUseRegisteredSuffixPattern());
235+
this.dispatcherServletPath.ifAvailable((dispatcherPath) -> {
236+
String servletUrlMapping = dispatcherPath.getServletUrlMapping();
237+
if (servletUrlMapping.equals("/")) {
238+
UrlPathHelper urlPathHelper = new UrlPathHelper();
239+
urlPathHelper.setAlwaysUseFullPath(true);
240+
configurer.setUrlPathHelper(urlPathHelper);
241+
}
242+
});
230243
}
231244

232245
@Override

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfigurationTests.java

+20-2
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@
118118
import org.springframework.web.servlet.resource.VersionStrategy;
119119
import org.springframework.web.servlet.view.AbstractView;
120120
import org.springframework.web.servlet.view.ContentNegotiatingViewResolver;
121+
import org.springframework.web.util.UrlPathHelper;
121122

122123
import static org.assertj.core.api.Assertions.assertThat;
123124
import static org.mockito.Mockito.mock;
@@ -139,8 +140,9 @@ class WebMvcAutoConfigurationTests {
139140
private static final MockServletWebServerFactory webServerFactory = new MockServletWebServerFactory();
140141

141142
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
142-
.withConfiguration(AutoConfigurations.of(WebMvcAutoConfiguration.class,
143-
HttpMessageConvertersAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class))
143+
.withConfiguration(
144+
AutoConfigurations.of(WebMvcAutoConfiguration.class, DispatcherServletAutoConfiguration.class,
145+
HttpMessageConvertersAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class))
144146
.withUserConfiguration(Config.class);
145147

146148
@Test
@@ -848,6 +850,22 @@ void customPrinterAndParserShouldBeRegisteredAsConverters() {
848850
});
849851
}
850852

853+
@Test
854+
void urlPathHelperUsesFullPathByDefault() {
855+
this.contextRunner.run((context) -> {
856+
UrlPathHelper urlPathHelper = context.getBean(UrlPathHelper.class);
857+
assertThat(urlPathHelper).extracting("alwaysUseFullPath").isEqualTo(true);
858+
});
859+
}
860+
861+
@Test
862+
void urlPathHelperDoesNotUseFullPathWithServletMapping() {
863+
this.contextRunner.withPropertyValues("spring.mvc.servlet.path=/test/").run((context) -> {
864+
UrlPathHelper urlPathHelper = context.getBean(UrlPathHelper.class);
865+
assertThat(urlPathHelper).extracting("alwaysUseFullPath").isEqualTo(false);
866+
});
867+
}
868+
851869
private void assertCacheControl(AssertableWebApplicationContext context) {
852870
Map<String, Object> handlerMap = getHandlerMap(context.getBean("resourceHandlerMapping", HandlerMapping.class));
853871
assertThat(handlerMap).hasSize(2);

0 commit comments

Comments
 (0)