diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java index 7fdab453c71..6d034d04ce5 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java @@ -139,7 +139,14 @@ public class ServerProperties implements EmbeddedServletContainerCustomizer, Ord } public void setContextPath(String contextPath) { - this.contextPath = contextPath; + this.contextPath = cleanContextPath(contextPath); + } + + private String cleanContextPath(String contextPath) { + if (StringUtils.hasText(contextPath) && contextPath.endsWith("/")) { + return contextPath.substring(0, contextPath.length() - 1); + } + return contextPath; } public String getDisplayName() { diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java index c34ac51b3b9..bab6847c868 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/ServerPropertiesTests.java @@ -41,6 +41,7 @@ import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletCont import org.springframework.boot.context.embedded.ServletContextInitializer; import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory; +import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.core.IsInstanceOf.instanceOf; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -123,6 +124,20 @@ public class ServerPropertiesTests { .getInternalProxies()); } + @Test + public void testTrailingSlashOfContextPathIsRemoved() { + new RelaxedDataBinder(this.properties, "server").bind(new MutablePropertyValues( + Collections.singletonMap("server.contextPath", "/foo/"))); + assertThat(this.properties.getContextPath(), equalTo("/foo")); + } + + @Test + public void testSlashOfContextPathIsDefaultValue() { + new RelaxedDataBinder(this.properties, "server").bind(new MutablePropertyValues( + Collections.singletonMap("server.contextPath", "/"))); + assertThat(this.properties.getContextPath(), equalTo("")); + } + @Test public void testCustomizeTomcat() throws Exception { ConfigurableEmbeddedServletContainer factory = mock(ConfigurableEmbeddedServletContainer.class);