Merge branch '4.1.x'

Closes gh-51983
This commit is contained in:
Stéphane Nicoll
2026-10-06 11:05:53 +02:00
2 changed files with 45 additions and 20 deletions
@@ -56,7 +56,6 @@ import org.springframework.boot.health.actuate.endpoint.HealthEndpoint;
import org.springframework.boot.health.actuate.endpoint.HealthEndpointGroups;
import org.springframework.boot.jersey.actuate.endpoint.web.JerseyEndpointResourceFactory;
import org.springframework.boot.jersey.actuate.endpoint.web.JerseyHealthEndpointAdditionalPathResourceFactory;
import org.springframework.boot.jersey.autoconfigure.ResourceConfigCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
@@ -71,6 +70,7 @@ import org.springframework.util.StringUtils;
* @author Michael Simons
* @author Madhura Bhave
* @author HaiTao Zhang
* @author Kristoffer Larsen Hopland
*/
@ManagementContextConfiguration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@@ -96,7 +96,7 @@ class JerseyWebEndpointManagementContextConfiguration {
@Bean
@ConditionalOnBean(org.springframework.boot.actuate.endpoint.jackson.EndpointJackson2ObjectMapper.class)
@SuppressWarnings("removal")
ResourceConfigCustomizer endpointJackson2ObjectMapperResourceConfigCustomizer(
ManagementContextResourceConfigCustomizer endpointJackson2ObjectMapperResourceConfigCustomizer(
org.springframework.boot.actuate.endpoint.jackson.EndpointJackson2ObjectMapper endpointJackson2ObjectMapper) {
return (config) -> config.register(
new EndpointJackson2ObjectMapperContextResolver(endpointJackson2ObjectMapper), ContextResolver.class);
@@ -31,6 +31,8 @@ import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer;
import org.glassfish.jersey.server.ResourceConfig;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
@@ -38,9 +40,12 @@ import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAu
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.jersey.autoconfigure.JerseyAutoConfiguration;
import org.springframework.boot.servlet.autoconfigure.actuate.web.ServletManagementContextAutoConfiguration;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.boot.tomcat.autoconfigure.actuate.web.server.TomcatServletManagementContextAutoConfiguration;
import org.springframework.boot.tomcat.autoconfigure.servlet.TomcatServletWebServerAutoConfiguration;
import org.springframework.boot.web.server.WebServer;
import org.springframework.boot.web.server.context.ServerPortInfoApplicationContextInitializer;
import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -53,6 +58,7 @@ import static org.assertj.core.api.Assertions.assertThat;
*
* @author Andy Wilkinson
* @author Madhura Bhave
* @author Kristoffer Larsen Hopland
*/
class JerseyEndpointIntegrationTests {
@@ -84,25 +90,44 @@ class JerseyEndpointIntegrationTests {
testJerseyEndpoints(new Class<?>[] { EndpointsConfiguration.class });
}
@Test
void endpointObjectMapperCanBeApplied() {
WebApplicationContextRunner contextRunner = getContextRunner(new Class<?>[] { EndpointsConfiguration.class,
ResourceConfigConfiguration.class, EndpointObjectMapperConfiguration.class });
contextRunner.run((context) -> {
WebServer webServer = context
.getSourceApplicationContext(AnnotationConfigServletWebServerApplicationContext.class)
.getWebServer();
assertThat(webServer).isNotNull();
int port = webServer.getPort();
WebTestClient client = WebTestClient.bindToServer()
.baseUrl("http://localhost:" + port)
.responseTimeout(Duration.ofMinutes(5))
.build();
client.get().uri("/actuator/beans").exchange().expectStatus().isOk().expectBody().consumeWith((result) -> {
String json = new String(result.getResponseBody(), StandardCharsets.UTF_8);
assertThat(json).contains("\"scope\":\"notelgnis\"");
@ParameterizedTest
@ValueSource(booleans = { false, true })
void endpointObjectMapperCanBeApplied(boolean separateManagementPort) {
getContextRunner(
new Class<?>[] { EndpointsConfiguration.class, ResourceConfigConfiguration.class,
EndpointObjectMapperConfiguration.class },
TomcatServletManagementContextAutoConfiguration.class, ServletManagementContextAutoConfiguration.class)
.with((runner) -> setUpManagementPort(runner, separateManagementPort))
.run((context) -> {
WebServer webServer = context
.getSourceApplicationContext(AnnotationConfigServletWebServerApplicationContext.class)
.getWebServer();
assertThat(webServer).isNotNull();
Integer port = separateManagementPort
? context.getEnvironment().getProperty("local.management.port", Integer.class)
: webServer.getPort();
assertThat(port).isNotNull();
WebTestClient client = WebTestClient.bindToServer()
.baseUrl("http://localhost:" + port)
.responseTimeout(Duration.ofMinutes(5))
.build();
client.get()
.uri("/actuator/beans")
.exchange()
.expectStatus()
.isOk()
.expectBody()
.consumeWith((result) -> {
String json = new String(result.getResponseBody(), StandardCharsets.UTF_8);
assertThat(json).contains("\"scope\":\"notelgnis\"");
});
});
});
}
private WebApplicationContextRunner setUpManagementPort(WebApplicationContextRunner runner,
boolean separateManagementPort) {
return (separateManagementPort) ? runner.withInitializer(new ServerPortInfoApplicationContextInitializer())
.withPropertyValues("management.server.port=0") : runner;
}
protected void testJerseyEndpoints(Class<?>[] userConfigurations) {