Set output_encoding in FreeMarkerView implementations
According to the official FreeMarker documentation, Spring's FreeMarkerView implementations should be configuring the output_encoding for template rendering. To address that, this commit modifies the FreeMarkerView implementations in Web MVC and WebFlux to explicitly set the output_encoding for template rendering. See https://freemarker.apache.org/docs/pgui_misc_charset.html#autoid_53 See gh-33071 Closes gh-33106
This commit is contained in:
@@ -26,6 +26,7 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import freemarker.core.Environment;
|
||||
import freemarker.core.ParseException;
|
||||
import freemarker.template.Configuration;
|
||||
import freemarker.template.DefaultObjectWrapperBuilder;
|
||||
@@ -333,7 +334,9 @@ public class FreeMarkerView extends AbstractUrlBasedView {
|
||||
FastByteArrayOutputStream bos = new FastByteArrayOutputStream();
|
||||
Charset charset = getCharset(contentType);
|
||||
Writer writer = new OutputStreamWriter(bos, charset);
|
||||
template.process(freeMarkerModel, writer);
|
||||
Environment env = template.createProcessingEnvironment(freeMarkerModel, writer);
|
||||
env.setOutputEncoding(charset.name());
|
||||
env.process();
|
||||
byte[] bytes = bos.toByteArrayUnsafe();
|
||||
DataBuffer buffer = exchange.getResponse().bufferFactory().wrap(bytes);
|
||||
return Mono.just(buffer);
|
||||
|
||||
@@ -58,12 +58,20 @@ class WebFluxViewResolutionIntegrationTests {
|
||||
|
||||
private static final MediaType TEXT_HTML_ISO_8859_1 = MediaType.parseMediaType("text/html;charset=ISO-8859-1");
|
||||
|
||||
private static final String EXPECTED_BODY = "<html><body>Hello, Java Café</body></html>";
|
||||
|
||||
|
||||
@Nested
|
||||
class FreeMarkerTests {
|
||||
|
||||
private static final String EXPECTED_BODY = """
|
||||
<html>
|
||||
<body>
|
||||
<h1>Hello, Java Café</h1>
|
||||
<p>output_encoding: %s</p>
|
||||
</body>
|
||||
</html>
|
||||
""";
|
||||
|
||||
private static final ClassTemplateLoader classTemplateLoader =
|
||||
new ClassTemplateLoader(WebFluxViewResolutionIntegrationTests.class, "");
|
||||
|
||||
@@ -77,21 +85,21 @@ class WebFluxViewResolutionIntegrationTests {
|
||||
@Test
|
||||
void freemarkerWithDefaults() throws Exception {
|
||||
MockServerHttpResponse response = runTest(FreeMarkerWebFluxConfig.class);
|
||||
StepVerifier.create(response.getBodyAsString()).expectNext(EXPECTED_BODY).expectComplete().verify();
|
||||
StepVerifier.create(response.getBodyAsString()).expectNext(EXPECTED_BODY.formatted("UTF-8")).expectComplete().verify();
|
||||
assertThat(response.getHeaders().getContentType()).isEqualTo(TEXT_HTML_UTF8);
|
||||
}
|
||||
|
||||
@Test
|
||||
void freemarkerWithExplicitDefaultEncoding() throws Exception {
|
||||
MockServerHttpResponse response = runTest(ExplicitDefaultEncodingConfig.class);
|
||||
StepVerifier.create(response.getBodyAsString()).expectNext(EXPECTED_BODY).expectComplete().verify();
|
||||
StepVerifier.create(response.getBodyAsString()).expectNext(EXPECTED_BODY.formatted("UTF-8")).expectComplete().verify();
|
||||
assertThat(response.getHeaders().getContentType()).isEqualTo(TEXT_HTML_UTF8);
|
||||
}
|
||||
|
||||
@Test
|
||||
void freemarkerWithExplicitDefaultEncodingAndContentType() throws Exception {
|
||||
MockServerHttpResponse response = runTest(ExplicitDefaultEncodingAndContentTypeConfig.class);
|
||||
StepVerifier.create(response.getBodyAsString()).expectNext(EXPECTED_BODY).expectComplete().verify();
|
||||
StepVerifier.create(response.getBodyAsString()).expectNext(EXPECTED_BODY.formatted("ISO-8859-1")).expectComplete().verify();
|
||||
// When the Content-Type (supported media type) is explicitly set on the view resolver, it should be used.
|
||||
assertThat(response.getHeaders().getContentType()).isEqualTo(TEXT_HTML_ISO_8859_1);
|
||||
}
|
||||
|
||||
@@ -1 +1,6 @@
|
||||
<html><body>${hello}, Java Caf<61></body></html>
|
||||
<html>
|
||||
<body>
|
||||
<h1>${hello}, Java Caf<61></h1>
|
||||
<p>output_encoding: ${.output_encoding}</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1 +1,6 @@
|
||||
<html><body>${hello}, Java Café</body></html>
|
||||
<html>
|
||||
<body>
|
||||
<h1>${hello}, Java Café</h1>
|
||||
<p>output_encoding: ${.output_encoding}</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user