Browse Source

Update Content-Type based on encoding in MVC FreeMarkerView

Closes gh-33119
pull/33134/head
Sam Brannen 2 years ago
parent
commit
b64edb2d2a
  1. 3
      framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-freemarker.adoc
  2. 17
      spring-context-support/src/main/java/org/springframework/ui/freemarker/FreeMarkerConfigurationFactory.java
  3. 2
      spring-context-support/src/main/java/org/springframework/ui/freemarker/FreeMarkerConfigurationFactoryBean.java
  4. 2
      spring-webflux/src/main/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerConfig.java
  5. 2
      spring-webflux/src/main/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerConfigurer.java
  6. 4
      spring-webflux/src/main/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerView.java
  7. 4
      spring-webflux/src/main/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerViewResolver.java
  8. 2
      spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerConfig.java
  9. 2
      spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerConfigurer.java
  10. 20
      spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerView.java
  11. 77
      spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerViewResolver.java
  12. 53
      spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ViewResolutionIntegrationTests.java

3
framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-freemarker.adoc

@ -36,6 +36,7 @@ Java::
public FreeMarkerConfigurer freeMarkerConfigurer() { public FreeMarkerConfigurer freeMarkerConfigurer() {
FreeMarkerConfigurer configurer = new FreeMarkerConfigurer(); FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
configurer.setTemplateLoaderPath("/WEB-INF/freemarker"); configurer.setTemplateLoaderPath("/WEB-INF/freemarker");
configurer.setDefaultCharset(StandardCharsets.UTF_8);
return configurer; return configurer;
} }
} }
@ -58,6 +59,7 @@ Kotlin::
@Bean @Bean
fun freeMarkerConfigurer() = FreeMarkerConfigurer().apply { fun freeMarkerConfigurer() = FreeMarkerConfigurer().apply {
setTemplateLoaderPath("/WEB-INF/freemarker") setTemplateLoaderPath("/WEB-INF/freemarker")
setDefaultCharset(StandardCharsets.UTF_8)
} }
} }
---- ----
@ -86,6 +88,7 @@ properties, as the following example shows:
---- ----
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"> <bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/WEB-INF/freemarker/"/> <property name="templateLoaderPath" value="/WEB-INF/freemarker/"/>
<property name="defaultEncoding" value="UTF-8"/>
</bean> </bean>
---- ----

17
spring-context-support/src/main/java/org/springframework/ui/freemarker/FreeMarkerConfigurationFactory.java

@ -62,7 +62,7 @@ import org.springframework.util.CollectionUtils;
* <p>The simplest way to use this class is to specify a "templateLoaderPath"; * <p>The simplest way to use this class is to specify a "templateLoaderPath";
* FreeMarker does not need any further configuration then. * FreeMarker does not need any further configuration then.
* *
* <p>Note: Spring's FreeMarker support requires FreeMarker 2.3.21 or higher. * <p>Note: Spring's FreeMarker support requires FreeMarker 2.3.26 or higher.
* *
* @author Darren Davison * @author Darren Davison
* @author Juergen Hoeller * @author Juergen Hoeller
@ -143,15 +143,18 @@ public class FreeMarkerConfigurationFactory {
* files. * files.
* <p>If not specified, FreeMarker will read template files using the platform * <p>If not specified, FreeMarker will read template files using the platform
* file encoding (defined by the JVM system property {@code file.encoding}) * file encoding (defined by the JVM system property {@code file.encoding})
* or {@code "utf-8"} if the platform file encoding is undefined. * or UTF-8 if the platform file encoding is undefined.
* <p>Note that the encoding is not used for template rendering. Instead, an * <p>Note that the supplied encoding may or may not be used for template
* explicit encoding must be specified for the rendering process &mdash; for * rendering. See the documentation for Spring's {@code FreeMarkerView} and
* example, via Spring's {@code FreeMarkerView} or {@code FreeMarkerViewResolver}. * {@code FreeMarkerViewResolver} implementations for further details.
* @see #setDefaultEncoding(Charset) * @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
* @see org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver#setContentType * @see org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver#setContentType
* @see org.springframework.web.reactive.result.view.freemarker.FreeMarkerView#setEncoding
* @see org.springframework.web.reactive.result.view.freemarker.FreeMarkerView#setSupportedMediaTypes
* @see org.springframework.web.reactive.result.view.freemarker.FreeMarkerViewResolver#setSupportedMediaTypes
*/ */
public void setDefaultEncoding(String defaultEncoding) { public void setDefaultEncoding(String defaultEncoding) {
this.defaultEncoding = defaultEncoding; this.defaultEncoding = defaultEncoding;
@ -170,7 +173,7 @@ public class FreeMarkerConfigurationFactory {
} }
/** /**
* 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.
* <p>For example, one or more custom loaders such as database loaders could * <p>For example, one or more custom loaders such as database loaders could
* be configured and injected here. * be configured and injected here.
@ -186,7 +189,7 @@ public class FreeMarkerConfigurationFactory {
} }
/** /**
* 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.
* <p>For example, one or more custom loaders such as database loaders could * <p>For example, one or more custom loaders such as database loaders could
* be configured and injected here. * be configured and injected here.

2
spring-context-support/src/main/java/org/springframework/ui/freemarker/FreeMarkerConfigurationFactoryBean.java

@ -45,7 +45,7 @@ import org.springframework.lang.Nullable;
* <p>See the {@link FreeMarkerConfigurationFactory} base class for configuration * <p>See the {@link FreeMarkerConfigurationFactory} base class for configuration
* details. * details.
* *
* <p>Note: Spring's FreeMarker support requires FreeMarker 2.3.21 or higher. * <p>Note: Spring's FreeMarker support requires FreeMarker 2.3.26 or higher.
* *
* @author Darren Davison * @author Darren Davison
* @since 03.03.2004 * @since 03.03.2004

2
spring-webflux/src/main/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerConfig.java

@ -24,6 +24,8 @@ import freemarker.template.Configuration;
* *
* <p>Detected and used by {@link FreeMarkerView}. * <p>Detected and used by {@link FreeMarkerView}.
* *
* <p>Note: Spring's FreeMarker support requires FreeMarker 2.3.26 or higher.
*
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
* @since 5.0 * @since 5.0
*/ */

2
spring-webflux/src/main/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerConfigurer.java

@ -56,7 +56,7 @@ import org.springframework.util.Assert;
* &lt;@spring.bind "person.age"/&gt; * &lt;@spring.bind "person.age"/&gt;
* age is ${spring.status.value}</pre> * age is ${spring.status.value}</pre>
* *
* <p>Note: Spring's FreeMarker support requires FreeMarker 2.3.21 or higher. * <p>Note: Spring's FreeMarker support requires FreeMarker 2.3.26 or higher.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
* @since 5.0 * @since 5.0

4
spring-webflux/src/main/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerView.java

@ -90,7 +90,7 @@ import org.springframework.web.server.ServerWebExchange;
* sets the supported media type to {@code "text/html;charset=UTF-8"} by default. * sets the supported media type to {@code "text/html;charset=UTF-8"} by default.
* Thus, those default values are likely suitable for most applications. * Thus, those default values are likely suitable for most applications.
* *
* <p>Note: Spring's FreeMarker support requires FreeMarker 2.3.21 or higher. * <p>Note: Spring's FreeMarker support requires FreeMarker 2.3.26 or higher.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
* @author Sam Brannen * @author Sam Brannen
@ -158,7 +158,7 @@ public class FreeMarkerView extends AbstractUrlBasedView {
* <p>If the encoding is not explicitly set here or in the FreeMarker * <p>If the encoding is not explicitly set here or in the FreeMarker
* {@code Configuration}, FreeMarker will read template files using the platform * {@code Configuration}, FreeMarker will read template files using the platform
* file encoding (defined by the JVM system property {@code file.encoding}) * file encoding (defined by the JVM system property {@code file.encoding})
* or {@code "utf-8"} if the platform file encoding is undefined. Note, * or UTF-8 if the platform file encoding is undefined. Note,
* however, that {@link FreeMarkerConfigurer} sets the default encoding in the * however, that {@link FreeMarkerConfigurer} sets the default encoding in the
* FreeMarker {@code Configuration} to "UTF-8". * FreeMarker {@code Configuration} to "UTF-8".
* <p>It's recommended to specify the encoding in the FreeMarker {@code Configuration} * <p>It's recommended to specify the encoding in the FreeMarker {@code Configuration}

4
spring-webflux/src/main/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerViewResolver.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2020 the original author or authors. * Copyright 2002-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -26,6 +26,8 @@ import org.springframework.web.reactive.result.view.UrlBasedViewResolver;
* <p>The view class for all views generated by this resolver can be specified * <p>The view class for all views generated by this resolver can be specified
* via the "viewClass" property. See {@link UrlBasedViewResolver} for details. * via the "viewClass" property. See {@link UrlBasedViewResolver} for details.
* *
* <p>Note: Spring's FreeMarker support requires FreeMarker 2.3.26 or higher.
*
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
* @since 5.0 * @since 5.0
*/ */

2
spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerConfig.java

@ -24,6 +24,8 @@ import freemarker.template.Configuration;
* *
* <p>Detected and used by {@link FreeMarkerView}. * <p>Detected and used by {@link FreeMarkerView}.
* *
* <p>Note: Spring's FreeMarker support requires FreeMarker 2.3.26 or higher.
*
* @author Darren Davison * @author Darren Davison
* @author Rob Harrop * @author Rob Harrop
* @since 03.03.2004 * @since 03.03.2004

2
spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerConfigurer.java

@ -62,7 +62,7 @@ import org.springframework.util.Assert;
* &lt;@spring.bind "person.age"/&gt; * &lt;@spring.bind "person.age"/&gt;
* age is ${spring.status.value}</pre> * age is ${spring.status.value}</pre>
* *
* <p>Note: Spring's FreeMarker support requires FreeMarker 2.3.21 or higher. * <p>Note: Spring's FreeMarker support requires FreeMarker 2.3.26 or higher.
* *
* @author Darren Davison * @author Darren Davison
* @author Rob Harrop * @author Rob Harrop

20
spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerView.java

@ -56,8 +56,8 @@ import org.springframework.web.servlet.view.AbstractTemplateView;
* byte sequences to character sequences when reading the FreeMarker template file. * byte sequences to character sequences when reading the FreeMarker template file.
* Default is determined by the FreeMarker {@link Configuration}.</li> * Default is determined by the FreeMarker {@link Configuration}.</li>
* <li><b>{@link #setContentType(String) contentType}</b>: the content type of the * <li><b>{@link #setContentType(String) contentType}</b>: the content type of the
* rendered response. Defaults to {@code "text/html;charset=ISO-8859-1"} but should * rendered response. Defaults to {@code "text/html;charset=ISO-8859-1"} but may
* typically be set to a value that corresponds to the actual generated content * need to be set to a value that corresponds to the actual generated content
* type (see note below).</li> * type (see note below).</li>
* </ul> * </ul>
* *
@ -72,9 +72,13 @@ import org.springframework.web.servlet.view.AbstractTemplateView;
* {@code "text/html;charset=UTF-8"}. When using {@link FreeMarkerViewResolver} * {@code "text/html;charset=UTF-8"}. When using {@link FreeMarkerViewResolver}
* to create the view for you, set the * to create the view for you, set the
* {@linkplain FreeMarkerViewResolver#setContentType(String) content type} * {@linkplain FreeMarkerViewResolver#setContentType(String) content type}
* directly in the {@code FreeMarkerViewResolver}. * directly in the {@code FreeMarkerViewResolver}; however, as of Spring Framework
* 6.2, it is no longer necessary to explicitly set the content type in the
* {@code FreeMarkerViewResolver} if you have set an explicit encoding via either
* {@link #setEncoding(String)}, {@link FreeMarkerConfigurer#setDefaultEncoding(String)},
* or {@link Configuration#setDefaultEncoding(String)}.
* *
* <p>Note: Spring's FreeMarker support requires FreeMarker 2.3.21 or higher. * <p>Note: Spring's FreeMarker support requires FreeMarker 2.3.26 or higher.
* As of Spring Framework 6.0, FreeMarker templates are rendered in a minimal * As of Spring Framework 6.0, FreeMarker templates are rendered in a minimal
* fashion without JSP support, just exposing request attributes in addition * fashion without JSP support, just exposing request attributes in addition
* to the MVC-provided model map for alignment with common Servlet resources. * to the MVC-provided model map for alignment with common Servlet resources.
@ -109,13 +113,11 @@ public class FreeMarkerView extends AbstractTemplateView {
* <p>If the encoding is not explicitly set here or in the FreeMarker * <p>If the encoding is not explicitly set here or in the FreeMarker
* {@code Configuration}, FreeMarker will read template files using the platform * {@code Configuration}, FreeMarker will read template files using the platform
* file encoding (defined by the JVM system property {@code file.encoding}) * file encoding (defined by the JVM system property {@code file.encoding})
* or {@code "utf-8"} if the platform file encoding is undefined. * or UTF-8 if the platform file encoding is undefined.
* <p>It's recommended to specify the encoding in the FreeMarker {@code Configuration} * <p>It's recommended to specify the encoding in the FreeMarker {@code Configuration}
* rather than per template if all your templates share a common encoding. * rather than per template if all your templates share a common encoding.
* <p>Note that the specified or default encoding is not used for template * <p>See the note in the {@linkplain FreeMarkerView class-level documentation}
* rendering. Instead, an explicit encoding must be specified for the rendering * for details regarding the encoding used to render the response.
* process. See the note in the {@linkplain FreeMarkerView class-level
* documentation} for details.
* @see freemarker.template.Configuration#setDefaultEncoding * @see freemarker.template.Configuration#setDefaultEncoding
* @see #setCharset(Charset) * @see #setCharset(Charset)
* @see #getEncoding() * @see #getEncoding()

77
spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerViewResolver.java

@ -16,6 +16,13 @@
package org.springframework.web.servlet.view.freemarker; package org.springframework.web.servlet.view.freemarker;
import java.util.Locale;
import freemarker.template.Configuration;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.view.AbstractTemplateViewResolver; import org.springframework.web.servlet.view.AbstractTemplateViewResolver;
import org.springframework.web.servlet.view.AbstractUrlBasedView; import org.springframework.web.servlet.view.AbstractUrlBasedView;
@ -29,12 +36,19 @@ import org.springframework.web.servlet.view.AbstractUrlBasedView;
* <p><b>Note:</b> To ensure that the correct encoding is used when the rendering * <p><b>Note:</b> To ensure that the correct encoding is used when the rendering
* the response, set the {@linkplain #setContentType(String) content type} with an * the response, set the {@linkplain #setContentType(String) content type} with an
* appropriate {@code charset} attribute &mdash; for example, * appropriate {@code charset} attribute &mdash; for example,
* {@code "text/html;charset=UTF-8"}. * {@code "text/html;charset=UTF-8"}; however, as of Spring Framework 6.2, it is
* no longer strictly necessary to explicitly set the content type in the
* {@code FreeMarkerViewResolver} if you have set an explicit encoding via either
* {@link FreeMarkerView#setEncoding(String)},
* {@link FreeMarkerConfigurer#setDefaultEncoding(String)}, or
* {@link Configuration#setDefaultEncoding(String)}.
* *
* <p><b>Note:</b> When chaining ViewResolvers, a {@code FreeMarkerViewResolver} will * <p><b>Note:</b> When chaining ViewResolvers, a {@code FreeMarkerViewResolver} will
* check for the existence of the specified template resources and only return * check for the existence of the specified template resources and only return
* a non-null {@code View} object if the template was actually found. * a non-null {@code View} object if the template was actually found.
* *
* <p>Note: Spring's FreeMarker support requires FreeMarker 2.3.26 or higher.
*
* @author Juergen Hoeller * @author Juergen Hoeller
* @author Sam Brannen * @author Sam Brannen
* @since 1.1 * @since 1.1
@ -83,4 +97,65 @@ public class FreeMarkerViewResolver extends AbstractTemplateViewResolver {
return (getViewClass() == FreeMarkerView.class ? new FreeMarkerView() : super.instantiateView()); return (getViewClass() == FreeMarkerView.class ? new FreeMarkerView() : super.instantiateView());
} }
/**
* Delegates to {@code super.loadView(viewName, locale)} for standard behavior
* and then to {@link #postProcessView(FreeMarkerView)} for customization.
* @since 6.2
* @see org.springframework.web.servlet.view.UrlBasedViewResolver#loadView(String, Locale)
* @see #postProcessView(FreeMarkerView)
*/
@Override
@Nullable
protected View loadView(String viewName, Locale locale) throws Exception {
View view = super.loadView(viewName, locale);
if (view instanceof FreeMarkerView freeMarkerView) {
postProcessView(freeMarkerView);
}
return view;
}
/**
* Post process the supplied {@link FreeMarkerView} after it has been {@linkplain
* org.springframework.web.servlet.view.UrlBasedViewResolver#loadView(String, Locale)
* loaded}.
* <p>The default implementation attempts to override the
* {@linkplain org.springframework.web.servlet.view.AbstractView#setContentType(String)
* content type} of the view with {@code "text/html;charset=<encoding>"},
* where {@code <encoding>} is equal to an explicitly configured character
* encoding for the underlying FreeMarker template file. If an explicit content
* type has been configured for this view resolver or if no explicit character
* encoding has been configured for the template file, this method does not
* modify the supplied {@code FreeMarkerView}.
* @since 6.2
* @see #loadView(String, Locale)
* @see #setContentType(String)
* @see org.springframework.web.servlet.view.AbstractView#setContentType(String)
*/
protected void postProcessView(FreeMarkerView freeMarkerView) {
// If an explicit content type has been configured for all views, it has
// already been set in the view in UrlBasedViewResolver#buildView(String),
// and there is no need to override it here.
if (getContentType() != null) {
return;
}
// Check if the view has an explicit encoding set.
String encoding = freeMarkerView.getEncoding();
if (encoding == null) {
// If an explicit encoding has not been configured for this particular view,
// use the explicit default encoding for the FreeMarker Configuration, if set.
Configuration configuration = freeMarkerView.obtainConfiguration();
if (configuration.isDefaultEncodingExplicitlySet()) {
encoding = configuration.getDefaultEncoding();
}
}
if (StringUtils.hasText(encoding)) {
String contentType = "text/html;charset=" + encoding;
if (logger.isDebugEnabled()) {
logger.debug("Setting Content-Type for view [%s] to: %s".formatted(freeMarkerView, contentType));
}
freeMarkerView.setContentType(contentType);
}
}
} }

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

@ -57,6 +57,8 @@ class ViewResolutionIntegrationTests {
@Nested @Nested
class FreeMarkerTests { class FreeMarkerTests {
private static final String DEFAULT_ENCODING = "ISO-8859-1";
private static final String EXPECTED_BODY = """ private static final String EXPECTED_BODY = """
<html> <html>
<body> <body>
@ -74,48 +76,37 @@ class ViewResolutionIntegrationTests {
} }
@Test @Test
void freemarkerWithDefaults() throws Exception { void freemarkerWithDefaultEncoding() throws Exception {
String encoding = "ISO-8859-1"; // Since no explicit encoding or content type has been set, we expect ISO-8859-1,
MockHttpServletResponse response = runTest(FreeMarkerWebConfig.class); // which is the default.
assertThat(response.isCharset()).as("character encoding set in response").isTrue(); runTestAndAssertResults(DEFAULT_ENCODING, FreeMarkerDefaultEncodingConfig.class);
assertThat(response.getContentAsString()).isEqualTo(EXPECTED_BODY.formatted(encoding));
// Prior to Spring Framework 6.2, the charset is not updated in the Content-Type.
// Thus, we expect ISO-8859-1 instead of UTF-8.
assertThat(response.getCharacterEncoding()).isEqualTo(encoding);
assertThat(response.getContentType()).isEqualTo("text/html;charset=" + encoding);
} }
@Test // gh-16629, gh-33071 @Test // gh-16629, gh-33071
void freemarkerWithExistingViewResolver() throws Exception { void freemarkerWithExistingViewResolverWithDefaultEncoding() throws Exception {
String encoding = "ISO-8859-1"; // Since no explicit encoding or content type has been set, we expect ISO-8859-1,
MockHttpServletResponse response = runTest(ExistingViewResolverConfig.class); // which is the default.
assertThat(response.isCharset()).as("character encoding set in response").isTrue(); runTestAndAssertResults(DEFAULT_ENCODING, ExistingViewResolverConfig.class);
assertThat(response.getContentAsString()).isEqualTo(EXPECTED_BODY.formatted(encoding));
// Prior to Spring Framework 6.2, the charset is not updated in the Content-Type.
// Thus, we expect ISO-8859-1 instead of UTF-8.
assertThat(response.getCharacterEncoding()).isEqualTo(encoding);
assertThat(response.getContentType()).isEqualTo("text/html;charset=" + encoding);
} }
@Test // gh-33071 @Test // gh-33071, gh-33119
void freemarkerWithExplicitDefaultEncoding() throws Exception { void freemarkerWithExplicitDefaultEncoding() throws Exception {
String encoding = "ISO-8859-1"; // As of Spring Framework 6.2, the charset is automatically updated in the Content-Type, as
MockHttpServletResponse response = runTest(ExplicitDefaultEncodingConfig.class); // long as the user didn't configure the Content-Type directly in the FreeMarkerViewResolver.
assertThat(response.isCharset()).as("character encoding set in response").isTrue(); runTestAndAssertResults("UTF-8", ExplicitDefaultEncodingConfig.class);
assertThat(response.getContentAsString()).isEqualTo(EXPECTED_BODY.formatted(encoding));
// Prior to Spring Framework 6.2, the charset is not updated in the Content-Type.
// Thus, we expect ISO-8859-1 instead of UTF-8.
assertThat(response.getCharacterEncoding()).isEqualTo(encoding);
assertThat(response.getContentType()).isEqualTo("text/html;charset=" + encoding);
} }
@Test // gh-33071 @Test // gh-33071
void freemarkerWithExplicitDefaultEncodingAndContentType() throws Exception { void freemarkerWithExplicitDefaultEncodingAndContentType() throws Exception {
String encoding = "UTF-16"; // When the Content-Type is explicitly set on the view resolver, it should be used.
MockHttpServletResponse response = runTest(ExplicitDefaultEncodingAndContentTypeConfig.class); runTestAndAssertResults("UTF-16", ExplicitDefaultEncodingAndContentTypeConfig.class);
}
private static void runTestAndAssertResults(String encoding, Class<?> configClass) throws Exception {
MockHttpServletResponse response = runTest(configClass);
assertThat(response.isCharset()).as("character encoding set in response").isTrue(); assertThat(response.isCharset()).as("character encoding set in response").isTrue();
assertThat(response.getContentAsString()).isEqualTo(EXPECTED_BODY.formatted(encoding)); assertThat(response.getContentAsString()).isEqualTo(EXPECTED_BODY.formatted(encoding));
// When the Content-Type is explicitly set on the view resolver, it should be used.
assertThat(response.getCharacterEncoding()).isEqualTo(encoding); assertThat(response.getCharacterEncoding()).isEqualTo(encoding);
assertThat(response.getContentType()).isEqualTo("text/html;charset=" + encoding); assertThat(response.getContentType()).isEqualTo("text/html;charset=" + encoding);
} }
@ -131,7 +122,7 @@ class ViewResolutionIntegrationTests {
} }
@Configuration @Configuration
static class FreeMarkerWebConfig extends AbstractWebConfig { static class FreeMarkerDefaultEncodingConfig extends AbstractWebConfig {
@Override @Override
public void configureViewResolvers(ViewResolverRegistry registry) { public void configureViewResolvers(ViewResolverRegistry registry) {

Loading…
Cancel
Save