diff --git a/spring-context-support/src/main/java/org/springframework/ui/freemarker/FreeMarkerConfigurationFactory.java b/spring-context-support/src/main/java/org/springframework/ui/freemarker/FreeMarkerConfigurationFactory.java index c3df6a706cf..f90a7fe6326 100644 --- a/spring-context-support/src/main/java/org/springframework/ui/freemarker/FreeMarkerConfigurationFactory.java +++ b/spring-context-support/src/main/java/org/springframework/ui/freemarker/FreeMarkerConfigurationFactory.java @@ -18,6 +18,7 @@ package org.springframework.ui.freemarker; import java.io.File; import java.io.IOException; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -146,6 +147,7 @@ public class FreeMarkerConfigurationFactory { *

Note that the encoding is not used for template rendering. Instead, an * explicit encoding must be specified for the rendering process — for * example, via Spring's {@code FreeMarkerView} or {@code FreeMarkerViewResolver}. + * @see #setDefaultEncoding(Charset) * @see freemarker.template.Configuration#setDefaultEncoding * @see org.springframework.web.servlet.view.freemarker.FreeMarkerView#setEncoding * @see org.springframework.web.servlet.view.freemarker.FreeMarkerView#setContentType @@ -155,6 +157,18 @@ public class FreeMarkerConfigurationFactory { this.defaultEncoding = defaultEncoding; } + /** + * Set the default encoding for the FreeMarker {@link Configuration}, which + * is used to decode byte sequences to character sequences when reading template + * files. + *

See {@link #setDefaultEncoding(String)} for details. + * @since 6.2 + * @see java.nio.charset.StandardCharsets + */ + public void setDefaultEncoding(Charset defaultEncoding) { + setDefaultEncoding(defaultEncoding.name()); + } + /** * Set a List of {@link TemplateLoader TemplateLoaders} that will be used to * search for templates. diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerConfigurer.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerConfigurer.java index 2159dbfb9f8..eba3fe69fa8 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerConfigurer.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerConfigurer.java @@ -17,6 +17,7 @@ package org.springframework.web.reactive.result.view.freemarker; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.List; import freemarker.cache.ClassTemplateLoader; @@ -68,7 +69,7 @@ public class FreeMarkerConfigurer extends FreeMarkerConfigurationFactory public FreeMarkerConfigurer() { - setDefaultEncoding("UTF-8"); + setDefaultEncoding(StandardCharsets.UTF_8); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerView.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerView.java index ff1af66f9ac..9a7d6f2867d 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerView.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerView.java @@ -167,12 +167,24 @@ public class FreeMarkerView extends AbstractUrlBasedView { * process. See the note in the {@linkplain FreeMarkerView class-level * documentation} for details. * @see freemarker.template.Configuration#setDefaultEncoding + * @see #setEncoding(Charset) * @see #getEncoding() */ public void setEncoding(@Nullable String encoding) { this.encoding = encoding; } + /** + * Set the encoding used to decode byte sequences to character sequences when + * reading the FreeMarker template file for this view. + *

See {@link #setEncoding(String)} for details. + * @since 6.2 + * @see java.nio.charset.StandardCharsets + */ + public void setEncoding(@Nullable Charset encoding) { + setEncoding(encoding != null ? encoding.name() : null); + } + /** * Get the encoding used to decode byte sequences to character sequences * when reading the FreeMarker template file for this view, or {@code null} @@ -364,7 +376,9 @@ public class FreeMarkerView extends AbstractUrlBasedView { } /** - * Get the FreeMarker template for the given locale, to be rendered by this view. + * Retrieve the FreeMarker {@link Template} to be rendered by this view, for + * the specified locale and using the {@linkplain #setEncoding(String) configured + * encoding} if set. *

By default, the template specified by the "url" bean property will be retrieved. * @param locale the current locale * @return the FreeMarker template to render @@ -379,7 +393,9 @@ public class FreeMarkerView extends AbstractUrlBasedView { } /** - * Retrieve the FreeMarker template for the given locale, to be rendered by this view. + * Retrieve the FreeMarker {@link Template} to be rendered by this view, for + * the specified locale and using the {@linkplain #setEncoding(String) configured + * encoding} if set. *

By default, the template specified by the "url" bean property will be retrieved, * and the returned mono will subscribe on the * {@linkplain Schedulers#boundedElastic() bounded elastic scheduler} as template diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/config/WebFluxViewResolutionIntegrationTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/config/WebFluxViewResolutionIntegrationTests.java index df1ccbd312b..b87b47a89bd 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/config/WebFluxViewResolutionIntegrationTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/config/WebFluxViewResolutionIntegrationTests.java @@ -135,7 +135,7 @@ class WebFluxViewResolutionIntegrationTests { public FreeMarkerConfigurer freeMarkerConfigurer() { FreeMarkerConfigurer configurer = new FreeMarkerConfigurer(); configurer.setPreTemplateLoaders(classTemplateLoader); - configurer.setDefaultEncoding(UTF_8.name()); + configurer.setDefaultEncoding(UTF_8); return configurer; } } @@ -158,7 +158,7 @@ class WebFluxViewResolutionIntegrationTests { public FreeMarkerConfigurer freeMarkerConfigurer() { FreeMarkerConfigurer configurer = new FreeMarkerConfigurer(); configurer.setPreTemplateLoaders(classTemplateLoader); - configurer.setDefaultEncoding(ISO_8859_1.name()); + configurer.setDefaultEncoding(ISO_8859_1); return configurer; } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerView.java index e513b5b2e71..80dae950e67 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerView.java @@ -18,6 +18,7 @@ package org.springframework.web.servlet.view.freemarker; import java.io.FileNotFoundException; import java.io.IOException; +import java.nio.charset.Charset; import java.util.Locale; import java.util.Map; @@ -115,6 +116,7 @@ public class FreeMarkerView extends AbstractTemplateView { * process. See the note in the {@linkplain FreeMarkerView class-level * documentation} for details. * @see freemarker.template.Configuration#setDefaultEncoding + * @see #setEncoding(Charset) * @see #getEncoding() * @see #setContentType(String) */ @@ -122,6 +124,17 @@ public class FreeMarkerView extends AbstractTemplateView { this.encoding = encoding; } + /** + * Set the encoding used to decode byte sequences to character sequences when + * reading the FreeMarker template file for this view. + *

See {@link #setEncoding(String)} for details. + * @since 6.2 + * @see java.nio.charset.StandardCharsets + */ + public void setEncoding(@Nullable Charset encoding) { + setEncoding(encoding != null ? encoding.name() : null); + } + /** * Get the encoding used to decode byte sequences to character sequences * when reading the FreeMarker template file for this view, or {@code null} @@ -316,10 +329,10 @@ public class FreeMarkerView extends AbstractTemplateView { } /** - * Retrieve the FreeMarker {@link Template} for the given locale, to be - * rendered by this view. - *

By default, the template specified by the "url" bean property - * will be retrieved. + * Retrieve the FreeMarker {@link Template} to be rendered by this view, for + * the specified locale and using the {@linkplain #setEncoding(String) configured + * encoding} if set. + *

By default, the template specified by the "url" bean property will be retrieved. * @param locale the current locale * @return the FreeMarker {@code Template} to render * @throws IOException if the template file could not be retrieved @@ -333,8 +346,9 @@ public class FreeMarkerView extends AbstractTemplateView { } /** - * Retrieve the FreeMarker {@link Template} for the specified name and locale, - * using the {@linkplain #setEncoding(String) configured encoding} if set. + * Retrieve the FreeMarker {@link Template} to be rendered by this view, for + * the specified name and locale and using the {@linkplain #setEncoding(String) + * configured encoding} if set. *

Can be called by subclasses to retrieve a specific template, * for example to render multiple templates into a single view. * @param name the file name of the desired template diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ViewResolutionIntegrationTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ViewResolutionIntegrationTests.java index 573a7cd5a24..94c76add16c 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ViewResolutionIntegrationTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ViewResolutionIntegrationTests.java @@ -16,8 +16,6 @@ package org.springframework.web.servlet.config.annotation; -import java.nio.charset.StandardCharsets; - import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -37,6 +35,7 @@ import org.springframework.web.testfixture.servlet.MockHttpServletResponse; import org.springframework.web.testfixture.servlet.MockServletConfig; import org.springframework.web.testfixture.servlet.MockServletContext; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatRuntimeException; @@ -165,7 +164,7 @@ class ViewResolutionIntegrationTests { public FreeMarkerConfigurer freeMarkerConfigurer() { FreeMarkerConfigurer configurer = new FreeMarkerConfigurer(); configurer.setTemplateLoaderPath("/WEB-INF/"); - configurer.setDefaultEncoding(StandardCharsets.UTF_8.name()); + configurer.setDefaultEncoding(UTF_8); return configurer; } } @@ -184,7 +183,7 @@ class ViewResolutionIntegrationTests { public FreeMarkerConfigurer freeMarkerConfigurer() { FreeMarkerConfigurer configurer = new FreeMarkerConfigurer(); configurer.setTemplateLoaderPath("/WEB-INF/"); - configurer.setDefaultEncoding(StandardCharsets.UTF_8.name()); + configurer.setDefaultEncoding(UTF_8); return configurer; } }