Browse Source

Allow encoding to be set with a Charset in FreeMarker support

Closes gh-33102
pull/33105/head
Sam Brannen 1 year ago
parent
commit
73c0783df1
  1. 14
      spring-context-support/src/main/java/org/springframework/ui/freemarker/FreeMarkerConfigurationFactory.java
  2. 3
      spring-webflux/src/main/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerConfigurer.java
  3. 20
      spring-webflux/src/main/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerView.java
  4. 4
      spring-webflux/src/test/java/org/springframework/web/reactive/config/WebFluxViewResolutionIntegrationTests.java
  5. 26
      spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerView.java
  6. 7
      spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ViewResolutionIntegrationTests.java

14
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.File;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -146,6 +147,7 @@ public class FreeMarkerConfigurationFactory {
* <p>Note that the encoding is not used for template rendering. Instead, an * <p>Note that the encoding is not used for template rendering. Instead, an
* explicit encoding must be specified for the rendering process &mdash; for * explicit encoding must be specified for the rendering process &mdash; for
* example, via Spring's {@code FreeMarkerView} or {@code FreeMarkerViewResolver}. * example, via Spring's {@code FreeMarkerView} or {@code FreeMarkerViewResolver}.
* @see #setDefaultEncoding(Charset)
* @see freemarker.template.Configuration#setDefaultEncoding * @see freemarker.template.Configuration#setDefaultEncoding
* @see org.springframework.web.servlet.view.freemarker.FreeMarkerView#setEncoding * @see org.springframework.web.servlet.view.freemarker.FreeMarkerView#setEncoding
* @see org.springframework.web.servlet.view.freemarker.FreeMarkerView#setContentType * @see org.springframework.web.servlet.view.freemarker.FreeMarkerView#setContentType
@ -155,6 +157,18 @@ public class FreeMarkerConfigurationFactory {
this.defaultEncoding = defaultEncoding; 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.
* <p>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 * Set a List of {@link TemplateLoader TemplateLoaders} that will be used to
* search for templates. * search for templates.

3
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; package org.springframework.web.reactive.result.view.freemarker;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List; import java.util.List;
import freemarker.cache.ClassTemplateLoader; import freemarker.cache.ClassTemplateLoader;
@ -68,7 +69,7 @@ public class FreeMarkerConfigurer extends FreeMarkerConfigurationFactory
public FreeMarkerConfigurer() { public FreeMarkerConfigurer() {
setDefaultEncoding("UTF-8"); setDefaultEncoding(StandardCharsets.UTF_8);
} }

20
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 * process. See the note in the {@linkplain FreeMarkerView class-level
* documentation} for details. * documentation} for details.
* @see freemarker.template.Configuration#setDefaultEncoding * @see freemarker.template.Configuration#setDefaultEncoding
* @see #setEncoding(Charset)
* @see #getEncoding() * @see #getEncoding()
*/ */
public void setEncoding(@Nullable String encoding) { public void setEncoding(@Nullable String encoding) {
this.encoding = encoding; this.encoding = encoding;
} }
/**
* Set the encoding used to decode byte sequences to character sequences when
* reading the FreeMarker template file for this view.
* <p>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 * Get the encoding used to decode byte sequences to character sequences
* when reading the FreeMarker template file for this view, or {@code null} * 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.
* <p>By default, the template specified by the "url" bean property will be retrieved. * <p>By default, the template specified by the "url" bean property will be retrieved.
* @param locale the current locale * @param locale the current locale
* @return the FreeMarker template to render * @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.
* <p>By default, the template specified by the "url" bean property will be retrieved, * <p>By default, the template specified by the "url" bean property will be retrieved,
* and the returned mono will subscribe on the * and the returned mono will subscribe on the
* {@linkplain Schedulers#boundedElastic() bounded elastic scheduler} as template * {@linkplain Schedulers#boundedElastic() bounded elastic scheduler} as template

4
spring-webflux/src/test/java/org/springframework/web/reactive/config/WebFluxViewResolutionIntegrationTests.java

@ -135,7 +135,7 @@ class WebFluxViewResolutionIntegrationTests {
public FreeMarkerConfigurer freeMarkerConfigurer() { public FreeMarkerConfigurer freeMarkerConfigurer() {
FreeMarkerConfigurer configurer = new FreeMarkerConfigurer(); FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
configurer.setPreTemplateLoaders(classTemplateLoader); configurer.setPreTemplateLoaders(classTemplateLoader);
configurer.setDefaultEncoding(UTF_8.name()); configurer.setDefaultEncoding(UTF_8);
return configurer; return configurer;
} }
} }
@ -158,7 +158,7 @@ class WebFluxViewResolutionIntegrationTests {
public FreeMarkerConfigurer freeMarkerConfigurer() { public FreeMarkerConfigurer freeMarkerConfigurer() {
FreeMarkerConfigurer configurer = new FreeMarkerConfigurer(); FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
configurer.setPreTemplateLoaders(classTemplateLoader); configurer.setPreTemplateLoaders(classTemplateLoader);
configurer.setDefaultEncoding(ISO_8859_1.name()); configurer.setDefaultEncoding(ISO_8859_1);
return configurer; return configurer;
} }

26
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.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
@ -115,6 +116,7 @@ public class FreeMarkerView extends AbstractTemplateView {
* process. See the note in the {@linkplain FreeMarkerView class-level * process. See the note in the {@linkplain FreeMarkerView class-level
* documentation} for details. * documentation} for details.
* @see freemarker.template.Configuration#setDefaultEncoding * @see freemarker.template.Configuration#setDefaultEncoding
* @see #setEncoding(Charset)
* @see #getEncoding() * @see #getEncoding()
* @see #setContentType(String) * @see #setContentType(String)
*/ */
@ -122,6 +124,17 @@ public class FreeMarkerView extends AbstractTemplateView {
this.encoding = encoding; this.encoding = encoding;
} }
/**
* Set the encoding used to decode byte sequences to character sequences when
* reading the FreeMarker template file for this view.
* <p>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 * Get the encoding used to decode byte sequences to character sequences
* when reading the FreeMarker template file for this view, or {@code null} * 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 * Retrieve the FreeMarker {@link Template} to be rendered by this view, for
* rendered by this view. * the specified locale and using the {@linkplain #setEncoding(String) configured
* <p>By default, the template specified by the "url" bean property * encoding} if set.
* will be retrieved. * <p>By default, the template specified by the "url" bean property will be retrieved.
* @param locale the current locale * @param locale the current locale
* @return the FreeMarker {@code Template} to render * @return the FreeMarker {@code Template} to render
* @throws IOException if the template file could not be retrieved * @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, * Retrieve the FreeMarker {@link Template} to be rendered by this view, for
* using the {@linkplain #setEncoding(String) configured encoding} if set. * the specified name and locale and using the {@linkplain #setEncoding(String)
* configured encoding} if set.
* <p>Can be called by subclasses to retrieve a specific template, * <p>Can be called by subclasses to retrieve a specific template,
* for example to render multiple templates into a single view. * for example to render multiple templates into a single view.
* @param name the file name of the desired template * @param name the file name of the desired template

7
spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ViewResolutionIntegrationTests.java

@ -16,8 +16,6 @@
package org.springframework.web.servlet.config.annotation; package org.springframework.web.servlet.config.annotation;
import java.nio.charset.StandardCharsets;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test; 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.MockServletConfig;
import org.springframework.web.testfixture.servlet.MockServletContext; 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.assertThat;
import static org.assertj.core.api.Assertions.assertThatRuntimeException; import static org.assertj.core.api.Assertions.assertThatRuntimeException;
@ -165,7 +164,7 @@ class ViewResolutionIntegrationTests {
public FreeMarkerConfigurer freeMarkerConfigurer() { public FreeMarkerConfigurer freeMarkerConfigurer() {
FreeMarkerConfigurer configurer = new FreeMarkerConfigurer(); FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
configurer.setTemplateLoaderPath("/WEB-INF/"); configurer.setTemplateLoaderPath("/WEB-INF/");
configurer.setDefaultEncoding(StandardCharsets.UTF_8.name()); configurer.setDefaultEncoding(UTF_8);
return configurer; return configurer;
} }
} }
@ -184,7 +183,7 @@ class ViewResolutionIntegrationTests {
public FreeMarkerConfigurer freeMarkerConfigurer() { public FreeMarkerConfigurer freeMarkerConfigurer() {
FreeMarkerConfigurer configurer = new FreeMarkerConfigurer(); FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
configurer.setTemplateLoaderPath("/WEB-INF/"); configurer.setTemplateLoaderPath("/WEB-INF/");
configurer.setDefaultEncoding(StandardCharsets.UTF_8.name()); configurer.setDefaultEncoding(UTF_8);
return configurer; return configurer;
} }
} }

Loading…
Cancel
Save