diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafAutoConfiguration.java index a448a03e00..b48004186a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafAutoConfiguration.java @@ -69,6 +69,7 @@ import org.springframework.web.servlet.resource.ResourceUrlEncodingFilter; * @author Brian Clozel * @author Eddú Meléndez * @author Daniel Fernández + * @author Kazuki Shimizu */ @Configuration @EnableConfigurationProperties(ThymeleafProperties.class) @@ -131,13 +132,16 @@ public class ThymeleafAutoConfiguration { @Configuration protected static class ThymeleafDefaultConfiguration { + private final ThymeleafProperties properties; + private final Collection templateResolvers; private final Collection dialects; - public ThymeleafDefaultConfiguration( + public ThymeleafDefaultConfiguration(ThymeleafProperties properties, Collection templateResolvers, ObjectProvider> dialectsProvider) { + this.properties = properties; this.templateResolvers = templateResolvers; this.dialects = dialectsProvider.getIfAvailable(Collections::emptyList); } @@ -146,6 +150,7 @@ public class ThymeleafAutoConfiguration { @ConditionalOnMissingBean(SpringTemplateEngine.class) public SpringTemplateEngine templateEngine() { SpringTemplateEngine engine = new SpringTemplateEngine(); + engine.setEnableSpringELCompiler(this.properties.isEnableSpringElCompiler()); this.templateResolvers.forEach(engine::addTemplateResolver); this.dialects.forEach(engine::addDialect); return engine; @@ -215,12 +220,16 @@ public class ThymeleafAutoConfiguration { @ConditionalOnProperty(name = "spring.thymeleaf.enabled", matchIfMissing = true) static class ThymeleafReactiveConfiguration { + private final ThymeleafProperties properties; + private final Collection templateResolvers; private final Collection dialects; - ThymeleafReactiveConfiguration(Collection templateResolvers, + ThymeleafReactiveConfiguration(ThymeleafProperties properties, + Collection templateResolvers, ObjectProvider> dialectsProvider) { + this.properties = properties; this.templateResolvers = templateResolvers; this.dialects = dialectsProvider.getIfAvailable(Collections::emptyList); } @@ -231,6 +240,7 @@ public class ThymeleafAutoConfiguration { SpringWebFluxTemplateEngine engine = new SpringWebFluxTemplateEngine(); this.templateResolvers.forEach(engine::addTemplateResolver); this.dialects.forEach(engine::addDialect); + engine.setEnableSpringELCompiler(this.properties.isEnableSpringElCompiler()); return engine; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafProperties.java index 91085a43b3..1a65f77347 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafProperties.java @@ -30,6 +30,7 @@ import org.springframework.util.MimeType; * @author Stephane Nicoll * @author Brian Clozel * @author Daniel Fernández + * @author Kazuki Shimizu * @since 1.2.0 */ @ConfigurationProperties(prefix = "spring.thymeleaf") @@ -95,6 +96,11 @@ public class ThymeleafProperties { */ private String[] excludedViewNames; + /** + * Enable the SpringEL compiler in SpringEL expressions. + */ + private boolean enableSpringElCompiler; + /** * Enable Thymeleaf view resolution for Web frameworks. */ @@ -192,6 +198,14 @@ public class ThymeleafProperties { this.viewNames = viewNames; } + public boolean isEnableSpringElCompiler() { + return this.enableSpringElCompiler; + } + + public void setEnableSpringElCompiler(boolean enableSpringElCompiler) { + this.enableSpringElCompiler = enableSpringElCompiler; + } + public Reactive getReactive() { return this.reactive; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafReactiveAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafReactiveAutoConfigurationTests.java index 92fc598bb1..058ab89a37 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafReactiveAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafReactiveAutoConfigurationTests.java @@ -28,6 +28,7 @@ import org.junit.Test; import org.thymeleaf.TemplateEngine; import org.thymeleaf.context.Context; import org.thymeleaf.spring5.ISpringWebFluxTemplateEngine; +import org.thymeleaf.spring5.SpringWebFluxTemplateEngine; import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver; import org.thymeleaf.spring5.view.reactive.ThymeleafReactiveViewResolver; import org.thymeleaf.templateresolver.ITemplateResolver; @@ -51,6 +52,7 @@ import static org.hamcrest.Matchers.not; * Tests for {@link ThymeleafAutoConfiguration} in Reactive applications. * * @author Brian Clozel + * @author Kazuki Shimizu */ public class ThymeleafReactiveAutoConfigurationTests { @@ -139,6 +141,20 @@ public class ThymeleafReactiveAutoConfigurationTests { .isEqualTo(new String[] { "foo", "bar" }); } + @Test + public void overrideEnableSpringElCompiler() { + load(BaseConfiguration.class, "spring.thymeleaf.enable-spring-el-compiler:true"); + assertThat(this.context.getBean(SpringWebFluxTemplateEngine.class) + .getEnableSpringELCompiler()).isTrue(); + } + + @Test + public void enableSpringElCompilerIsDisabledByDefault() { + load(BaseConfiguration.class); + assertThat(this.context.getBean(SpringWebFluxTemplateEngine.class) + .getEnableSpringELCompiler()).isFalse(); + } + @Test public void templateLocationDoesNotExist() throws Exception { load(BaseConfiguration.class, diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafServletAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafServletAutoConfigurationTests.java index 4c5b3ec4bd..9362d91f81 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafServletAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafServletAutoConfigurationTests.java @@ -27,6 +27,7 @@ import org.junit.Rule; import org.junit.Test; import org.thymeleaf.TemplateEngine; import org.thymeleaf.context.Context; +import org.thymeleaf.spring5.SpringTemplateEngine; import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver; import org.thymeleaf.spring5.view.ThymeleafView; import org.thymeleaf.spring5.view.ThymeleafViewResolver; @@ -59,6 +60,7 @@ import static org.hamcrest.Matchers.containsString; * @author Stephane Nicoll * @author Eddú Meléndez * @author Brian Clozel + * @author Kazuki Shimizu */ public class ThymeleafServletAutoConfigurationTests { @@ -110,6 +112,20 @@ public class ThymeleafServletAutoConfigurationTests { assertThat(views.getViewNames()).isEqualTo(new String[] { "foo", "bar" }); } + @Test + public void overrideEnableSpringElCompiler() { + load(BaseConfiguration.class, "spring.thymeleaf.enable-spring-el-compiler:true"); + assertThat(this.context.getBean(SpringTemplateEngine.class) + .getEnableSpringELCompiler()).isTrue(); + } + + @Test + public void enableSpringElCompilerIsDisabledByDefault() { + load(BaseConfiguration.class); + assertThat(this.context.getBean(SpringTemplateEngine.class) + .getEnableSpringELCompiler()).isFalse(); + } + @Test public void templateLocationDoesNotExist() throws Exception { load(BaseConfiguration.class, diff --git a/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc b/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc index c764eb8846..d95e1e85bb 100644 --- a/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc +++ b/spring-boot-project/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc @@ -453,6 +453,7 @@ content into your application; rather pick only the properties that you need. spring.thymeleaf.check-template=true # Check that the template exists before rendering it. spring.thymeleaf.check-template-location=true # Check that the templates location exists. spring.thymeleaf.enabled=true # Enable Thymeleaf view resolution for Web frameworks. + spring.thymeleaf.enable-spring-el-compiler=false # Enable the SpringEL compiler in SpringEL expressions. spring.thymeleaf.encoding=UTF-8 # Template files encoding. spring.thymeleaf.excluded-view-names= # Comma-separated list of view names that should be excluded from resolution. spring.thymeleaf.mode=HTML5 # Template mode to be applied to templates. See also StandardTemplateModeHandlers.