diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/ServletEndpointManagementContextConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/ServletEndpointManagementContextConfiguration.java index b556ff9972..252a9d809a 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/ServletEndpointManagementContextConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/ServletEndpointManagementContextConfiguration.java @@ -16,35 +16,35 @@ package org.springframework.boot.actuate.autoconfigure.endpoint.web; +import org.glassfish.jersey.server.ResourceConfig; + import org.springframework.boot.actuate.autoconfigure.endpoint.ExposeExcludePropertyEndpointFilter; import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration; import org.springframework.boot.actuate.endpoint.web.ExposableServletEndpoint; import org.springframework.boot.actuate.endpoint.web.ServletEndpointRegistrar; import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPathProvider; +import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.DispatcherServlet; /** * {@link ManagementContextConfiguration} for servlet endpoints. * * @author Phillip Webb * @author Andy Wilkinson + * @author Madhura Bhave * @since 2.0.0 */ @Configuration @ConditionalOnWebApplication(type = Type.SERVLET) public class ServletEndpointManagementContextConfiguration { - @Bean - public ServletEndpointRegistrar servletEndpointRegistrar( - WebEndpointProperties properties, - ServletEndpointsSupplier servletEndpointsSupplier) { - return new ServletEndpointRegistrar(properties.getBasePath(), - servletEndpointsSupplier.getEndpoints()); - } - @Bean public ExposeExcludePropertyEndpointFilter servletExposeExcludePropertyEndpointFilter( WebEndpointProperties properties) { @@ -53,4 +53,41 @@ public class ServletEndpointManagementContextConfiguration { exposure.getInclude(), exposure.getExclude()); } + @Configuration + @ConditionalOnClass(DispatcherServlet.class) + public class WebMvcServletEndpointManagementContextConfiguration { + + private final ApplicationContext context; + + public WebMvcServletEndpointManagementContextConfiguration(ApplicationContext context) { + this.context = context; + } + + @Bean + public ServletEndpointRegistrar servletEndpointRegistrar( + WebEndpointProperties properties, + ServletEndpointsSupplier servletEndpointsSupplier) { + DispatcherServletPathProvider servletPathProvider = this.context.getBean(DispatcherServletPathProvider.class); + String servletPath = (servletPathProvider.getServletPath().equals("/") ? "" : servletPathProvider.getServletPath()); + return new ServletEndpointRegistrar(servletPath + properties.getBasePath(), + servletEndpointsSupplier.getEndpoints()); + } + + } + + @Configuration + @ConditionalOnClass(ResourceConfig.class) + @ConditionalOnMissingClass("org.springframework.web.servlet.DispatcherServlet") + public class JerseyServletEndpointManagementContextConfiguration { + + @Bean + public ServletEndpointRegistrar servletEndpointRegistrar( + WebEndpointProperties properties, + ServletEndpointsSupplier servletEndpointsSupplier) { + return new ServletEndpointRegistrar(properties.getBasePath(), + servletEndpointsSupplier.getEndpoints()); + } + + } + } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/ServletEndpointManagementContextConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/ServletEndpointManagementContextConfigurationTests.java index 4c47c53846..a0a78984e9 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/ServletEndpointManagementContextConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/ServletEndpointManagementContextConfigurationTests.java @@ -18,16 +18,21 @@ package org.springframework.boot.actuate.autoconfigure.endpoint.web; import java.util.Collections; +import org.glassfish.jersey.server.ResourceConfig; import org.junit.Test; import org.springframework.boot.actuate.endpoint.web.ServletEndpointRegistrar; import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier; +import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPathProvider; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import org.springframework.test.util.ReflectionTestUtils; +import org.springframework.web.servlet.DispatcherServlet; import static org.assertj.core.api.Assertions.assertThat; @@ -35,6 +40,7 @@ import static org.assertj.core.api.Assertions.assertThat; * Tests for {@link ServletEndpointManagementContextConfiguration}. * * @author Phillip Webb + * @author Madhura Bhave */ public class ServletEndpointManagementContextConfigurationTests { @@ -43,8 +49,28 @@ public class ServletEndpointManagementContextConfigurationTests { @Test public void contextShouldContainServletEndpointRegistrar() { - this.contextRunner.run((context) -> assertThat(context) - .hasSingleBean(ServletEndpointRegistrar.class)); + FilteredClassLoader classLoader = new FilteredClassLoader( + ResourceConfig.class); + this.contextRunner.withClassLoader(classLoader).run((context) -> { + assertThat(context) + .hasSingleBean(ServletEndpointRegistrar.class); + ServletEndpointRegistrar bean = context.getBean(ServletEndpointRegistrar.class); + String basePath = (String) ReflectionTestUtils.getField(bean, "basePath"); + assertThat(basePath).isEqualTo("/test/actuator"); + }); + } + + @Test + public void servletPathShouldNotAffectJerseyConfiguration() { + FilteredClassLoader classLoader = new FilteredClassLoader( + DispatcherServlet.class); + this.contextRunner.withClassLoader(classLoader).run((context) -> { + assertThat(context) + .hasSingleBean(ServletEndpointRegistrar.class); + ServletEndpointRegistrar bean = context.getBean(ServletEndpointRegistrar.class); + String basePath = (String) ReflectionTestUtils.getField(bean, "basePath"); + assertThat(basePath).isEqualTo("/actuator"); + }); } @Test @@ -64,6 +90,11 @@ public class ServletEndpointManagementContextConfigurationTests { return () -> Collections.emptyList(); } + @Bean + public DispatcherServletPathProvider servletPathProvider() { + return () -> "/test"; + } + } }