From b64edb2d2abf5068a0d5fa0289a809aa53803f0f Mon Sep 17 00:00:00 2001 From: Sam Brannen <104798+sbrannen@users.noreply.github.com> Date: Sat, 29 Jun 2024 16:20:34 +0200 Subject: [PATCH] Update Content-Type based on encoding in MVC FreeMarkerView Closes gh-33119 --- .../pages/web/webmvc-view/mvc-freemarker.adoc | 3 + .../FreeMarkerConfigurationFactory.java | 17 ++-- .../FreeMarkerConfigurationFactoryBean.java | 2 +- .../view/freemarker/FreeMarkerConfig.java | 2 + .../view/freemarker/FreeMarkerConfigurer.java | 2 +- .../view/freemarker/FreeMarkerView.java | 4 +- .../freemarker/FreeMarkerViewResolver.java | 4 +- .../view/freemarker/FreeMarkerConfig.java | 2 + .../view/freemarker/FreeMarkerConfigurer.java | 2 +- .../view/freemarker/FreeMarkerView.java | 20 ++--- .../freemarker/FreeMarkerViewResolver.java | 77 ++++++++++++++++++- .../ViewResolutionIntegrationTests.java | 53 ++++++------- 12 files changed, 134 insertions(+), 54 deletions(-) diff --git a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-freemarker.adoc b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-freemarker.adoc index e0e95083b98..7944f7c42bb 100644 --- a/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-freemarker.adoc +++ b/framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-freemarker.adoc @@ -36,6 +36,7 @@ Java:: public FreeMarkerConfigurer freeMarkerConfigurer() { FreeMarkerConfigurer configurer = new FreeMarkerConfigurer(); configurer.setTemplateLoaderPath("/WEB-INF/freemarker"); + configurer.setDefaultCharset(StandardCharsets.UTF_8); return configurer; } } @@ -58,6 +59,7 @@ Kotlin:: @Bean fun freeMarkerConfigurer() = FreeMarkerConfigurer().apply { setTemplateLoaderPath("/WEB-INF/freemarker") + setDefaultCharset(StandardCharsets.UTF_8) } } ---- @@ -86,6 +88,7 @@ properties, as the following example shows: ---- + ---- 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 434c61a7de7..f2933e86044 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 @@ -62,7 +62,7 @@ import org.springframework.util.CollectionUtils; *

The simplest way to use this class is to specify a "templateLoaderPath"; * FreeMarker does not need any further configuration then. * - *

Note: Spring's FreeMarker support requires FreeMarker 2.3.21 or higher. + *

Note: Spring's FreeMarker support requires FreeMarker 2.3.26 or higher. * * @author Darren Davison * @author Juergen Hoeller @@ -143,15 +143,18 @@ public class FreeMarkerConfigurationFactory { * files. *

If not specified, FreeMarker will read template files using the platform * file encoding (defined by the JVM system property {@code file.encoding}) - * or {@code "utf-8"} if the platform file encoding is undefined. - *

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}. + * or UTF-8 if the platform file encoding is undefined. + *

Note that the supplied encoding may or may not be used for template + * rendering. See the documentation for Spring's {@code FreeMarkerView} and + * {@code FreeMarkerViewResolver} implementations for further details. * @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 * @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) { 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. *

For example, one or more custom loaders such as database loaders could * 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. *

For example, one or more custom loaders such as database loaders could * be configured and injected here. diff --git a/spring-context-support/src/main/java/org/springframework/ui/freemarker/FreeMarkerConfigurationFactoryBean.java b/spring-context-support/src/main/java/org/springframework/ui/freemarker/FreeMarkerConfigurationFactoryBean.java index 3aac7d4df21..a98666a2a57 100644 --- a/spring-context-support/src/main/java/org/springframework/ui/freemarker/FreeMarkerConfigurationFactoryBean.java +++ b/spring-context-support/src/main/java/org/springframework/ui/freemarker/FreeMarkerConfigurationFactoryBean.java @@ -45,7 +45,7 @@ import org.springframework.lang.Nullable; *

See the {@link FreeMarkerConfigurationFactory} base class for configuration * details. * - *

Note: Spring's FreeMarker support requires FreeMarker 2.3.21 or higher. + *

Note: Spring's FreeMarker support requires FreeMarker 2.3.26 or higher. * * @author Darren Davison * @since 03.03.2004 diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerConfig.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerConfig.java index e30c3d9b601..7a4ede11193 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerConfig.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerConfig.java @@ -24,6 +24,8 @@ import freemarker.template.Configuration; * *

Detected and used by {@link FreeMarkerView}. * + *

Note: Spring's FreeMarker support requires FreeMarker 2.3.26 or higher. + * * @author Rossen Stoyanchev * @since 5.0 */ 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 76b54358ac3..b1a4318837e 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 @@ -56,7 +56,7 @@ import org.springframework.util.Assert; * <@spring.bind "person.age"/> * age is ${spring.status.value} * - *

Note: Spring's FreeMarker support requires FreeMarker 2.3.21 or higher. + *

Note: Spring's FreeMarker support requires FreeMarker 2.3.26 or higher. * * @author Rossen Stoyanchev * @since 5.0 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 89386db8958..955381dc164 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 @@ -90,7 +90,7 @@ import org.springframework.web.server.ServerWebExchange; * sets the supported media type to {@code "text/html;charset=UTF-8"} by default. * Thus, those default values are likely suitable for most applications. * - *

Note: Spring's FreeMarker support requires FreeMarker 2.3.21 or higher. + *

Note: Spring's FreeMarker support requires FreeMarker 2.3.26 or higher. * * @author Rossen Stoyanchev * @author Sam Brannen @@ -158,7 +158,7 @@ public class FreeMarkerView extends AbstractUrlBasedView { *

If the encoding is not explicitly set here or in the FreeMarker * {@code Configuration}, FreeMarker will read template files using the platform * 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 * FreeMarker {@code Configuration} to "UTF-8". *

It's recommended to specify the encoding in the FreeMarker {@code Configuration} diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerViewResolver.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerViewResolver.java index 89e021229e7..eb5663a4404 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/freemarker/FreeMarkerViewResolver.java +++ b/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"); * you may not use this file except in compliance with the License. @@ -26,6 +26,8 @@ import org.springframework.web.reactive.result.view.UrlBasedViewResolver; *

The view class for all views generated by this resolver can be specified * via the "viewClass" property. See {@link UrlBasedViewResolver} for details. * + *

Note: Spring's FreeMarker support requires FreeMarker 2.3.26 or higher. + * * @author Rossen Stoyanchev * @since 5.0 */ diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerConfig.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerConfig.java index abf21250472..e6b69901343 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerConfig.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerConfig.java @@ -24,6 +24,8 @@ import freemarker.template.Configuration; * *

Detected and used by {@link FreeMarkerView}. * + *

Note: Spring's FreeMarker support requires FreeMarker 2.3.26 or higher. + * * @author Darren Davison * @author Rob Harrop * @since 03.03.2004 diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerConfigurer.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerConfigurer.java index 3943bd1898b..24c1aa9445f 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerConfigurer.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerConfigurer.java @@ -62,7 +62,7 @@ import org.springframework.util.Assert; * <@spring.bind "person.age"/> * age is ${spring.status.value} * - *

Note: Spring's FreeMarker support requires FreeMarker 2.3.21 or higher. + *

Note: Spring's FreeMarker support requires FreeMarker 2.3.26 or higher. * * @author Darren Davison * @author Rob Harrop 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 533a398be21..0a1c2bee026 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 @@ -56,8 +56,8 @@ import org.springframework.web.servlet.view.AbstractTemplateView; * byte sequences to character sequences when reading the FreeMarker template file. * Default is determined by the FreeMarker {@link Configuration}. *

  • {@link #setContentType(String) contentType}: the content type of the - * rendered response. Defaults to {@code "text/html;charset=ISO-8859-1"} but should - * typically be set to a value that corresponds to the actual generated content + * rendered response. Defaults to {@code "text/html;charset=ISO-8859-1"} but may + * need to be set to a value that corresponds to the actual generated content * type (see note below).
  • * * @@ -72,9 +72,13 @@ import org.springframework.web.servlet.view.AbstractTemplateView; * {@code "text/html;charset=UTF-8"}. When using {@link FreeMarkerViewResolver} * to create the view for you, set the * {@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)}. * - *

    Note: Spring's FreeMarker support requires FreeMarker 2.3.21 or higher. + *

    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 * fashion without JSP support, just exposing request attributes in addition * to the MVC-provided model map for alignment with common Servlet resources. @@ -109,13 +113,11 @@ public class FreeMarkerView extends AbstractTemplateView { *

    If the encoding is not explicitly set here or in the FreeMarker * {@code Configuration}, FreeMarker will read template files using the platform * 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. *

    It's recommended to specify the encoding in the FreeMarker {@code Configuration} * rather than per template if all your templates share a common encoding. - *

    Note that the specified or default encoding is not used for template - * rendering. Instead, an explicit encoding must be specified for the rendering - * process. See the note in the {@linkplain FreeMarkerView class-level - * documentation} for details. + *

    See the note in the {@linkplain FreeMarkerView class-level documentation} + * for details regarding the encoding used to render the response. * @see freemarker.template.Configuration#setDefaultEncoding * @see #setCharset(Charset) * @see #getEncoding() diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerViewResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerViewResolver.java index 17c728dfe6a..9fed609f101 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerViewResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/freemarker/FreeMarkerViewResolver.java @@ -16,6 +16,13 @@ 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.AbstractUrlBasedView; @@ -29,12 +36,19 @@ import org.springframework.web.servlet.view.AbstractUrlBasedView; *

    Note: To ensure that the correct encoding is used when the rendering * the response, set the {@linkplain #setContentType(String) content type} with an * appropriate {@code charset} attribute — 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)}. * *

    Note: When chaining ViewResolvers, a {@code FreeMarkerViewResolver} will * check for the existence of the specified template resources and only return * a non-null {@code View} object if the template was actually found. * + *

    Note: Spring's FreeMarker support requires FreeMarker 2.3.26 or higher. + * * @author Juergen Hoeller * @author Sam Brannen * @since 1.1 @@ -83,4 +97,65 @@ public class FreeMarkerViewResolver extends AbstractTemplateViewResolver { 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}. + *

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