Merge pull request #49791 from husseinvr97

* gh-49623-default-html-escape-property:
  Polish "Add configuration for HTML escaping configuration with WebFlux"
  Add configuration for HTML escaping configuration with WebFlux

Closes gh-49791
This commit is contained in:
Stéphane Nicoll
2026-03-26 15:20:37 +01:00
3 changed files with 43 additions and 1 deletions
@@ -64,10 +64,13 @@ public final class HttpHandlerAutoConfiguration {
@Bean
HttpHandler httpHandler(ObjectProvider<WebFluxProperties> propsProvider,
ObjectProvider<WebHttpHandlerBuilderCustomizer> handlerBuilderCustomizers) {
WebFluxProperties properties = propsProvider.getIfAvailable();
WebHttpHandlerBuilder handlerBuilder = WebHttpHandlerBuilder.applicationContext(this.applicationContext);
if (properties != null) {
handlerBuilder.defaultHtmlEscape(properties.getDefaultHtmlEscape());
}
handlerBuilderCustomizers.orderedStream().forEach((customizer) -> customizer.customize(handlerBuilder));
HttpHandler httpHandler = handlerBuilder.build();
WebFluxProperties properties = propsProvider.getIfAvailable();
if (properties != null && StringUtils.hasText(properties.getBasePath())) {
Map<String, HttpHandler> handlersMap = Collections.singletonMap(properties.getBasePath(), httpHandler);
return new ContextPathCompositeHandler(handlersMap);
@@ -58,6 +58,11 @@ public class WebFluxProperties {
*/
private String webjarsPathPattern = "/webjars/**";
/**
* Whether default HTML escaping is enabled for the web application.
*/
private @Nullable Boolean defaultHtmlEscape;
public @Nullable String getBasePath() {
return this.basePath;
}
@@ -110,6 +115,14 @@ public class WebFluxProperties {
this.webjarsPathPattern = webjarsPathPattern;
}
public @Nullable Boolean getDefaultHtmlEscape() {
return this.defaultHtmlEscape;
}
public void setDefaultHtmlEscape(@Nullable Boolean defaultHtmlEscape) {
this.defaultHtmlEscape = defaultHtmlEscape;
}
public static class Format {
/**
@@ -18,6 +18,8 @@ package org.springframework.boot.webflux.autoconfigure;
import org.assertj.core.api.InstanceOfAssertFactories;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import reactor.core.publisher.Mono;
import org.springframework.boot.autoconfigure.AutoConfigurations;
@@ -35,6 +37,7 @@ import org.springframework.web.reactive.DispatcherHandler;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.server.WebHandler;
import org.springframework.web.server.adapter.HttpWebHandlerAdapter;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
@@ -100,6 +103,29 @@ class HttpHandlerAutoConfigurationTests {
});
}
@ParameterizedTest
@ValueSource(booleans = { true, false })
void shouldConfigureDefaultHtmlEscape(boolean enabled) {
this.contextRunner.withConfiguration(AutoConfigurations.of(WebFluxAutoConfiguration.class))
.withPropertyValues("spring.webflux.default-html-escape=" + enabled)
.run((context) -> {
assertThat(context).hasSingleBean(HttpHandler.class);
assertThat(context.getBean(HttpHandler.class)).isInstanceOfSatisfying(HttpWebHandlerAdapter.class,
(adapter) -> assertThat(adapter.getDefaultHtmlEscape()).isEqualTo(enabled));
});
}
@Test
void shouldNotConfigureDefaultHtmlEscaperWithoutWebFluxAutoConfiguration() {
this.contextRunner.withUserConfiguration(CustomWebHandler.class)
.withPropertyValues("spring.webflux.default-html-escape=true")
.run((context) -> {
assertThat(context).hasSingleBean(HttpHandler.class);
assertThat(context.getBean(HttpHandler.class)).isInstanceOfSatisfying(HttpWebHandlerAdapter.class,
(adapter) -> assertThat(adapter.getDefaultHtmlEscape()).isNull());
});
}
@Configuration(proxyBeanMethods = false)
static class CustomHttpHandler {