Remove web concerns from template package and move out of -all

See gh-46071

Co-authored-by: Phillip Webb <phil.webb@broadcom.com>
This commit is contained in:
Andy Wilkinson 2025-03-14 16:10:56 +00:00
parent 3f477c4b40
commit 1cb6a23cd5
14 changed files with 552 additions and 329 deletions

View File

@ -16,11 +16,17 @@
package org.springframework.boot.autoconfigure.freemarker; package org.springframework.boot.autoconfigure.freemarker;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import org.springframework.boot.autoconfigure.template.AbstractTemplateViewResolverProperties;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.Ordered;
import org.springframework.util.Assert;
import org.springframework.util.MimeType;
import org.springframework.web.servlet.view.AbstractTemplateViewResolver;
/** /**
* {@link ConfigurationProperties @ConfigurationProperties} for configuring FreeMarker. * {@link ConfigurationProperties @ConfigurationProperties} for configuring FreeMarker.
@ -30,7 +36,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
* @since 1.1.0 * @since 1.1.0
*/ */
@ConfigurationProperties("spring.freemarker") @ConfigurationProperties("spring.freemarker")
public class FreeMarkerProperties extends AbstractTemplateViewResolverProperties { public class FreeMarkerProperties {
public static final String DEFAULT_TEMPLATE_LOADER_PATH = "classpath:/templates/"; public static final String DEFAULT_TEMPLATE_LOADER_PATH = "classpath:/templates/";
@ -38,6 +44,85 @@ public class FreeMarkerProperties extends AbstractTemplateViewResolverProperties
public static final String DEFAULT_SUFFIX = ".ftlh"; public static final String DEFAULT_SUFFIX = ".ftlh";
private static final MimeType DEFAULT_CONTENT_TYPE = MimeType.valueOf("text/html");
private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
/**
* Whether to enable MVC view resolution for this technology.
*/
private boolean enabled = true;
/**
* Whether to enable template caching.
*/
private boolean cache;
/**
* Content-Type value.
*/
private MimeType contentType = DEFAULT_CONTENT_TYPE;
/**
* Template encoding.
*/
private Charset charset = DEFAULT_CHARSET;
/**
* View names that can be resolved.
*/
private String[] viewNames;
/**
* Whether to check that the templates location exists.
*/
private boolean checkTemplateLocation = true;
/**
* Prefix that gets prepended to view names when building a URL.
*/
private String prefix = DEFAULT_PREFIX;
/**
* Suffix that gets appended to view names when building a URL.
*/
private String suffix = DEFAULT_SUFFIX;
/**
* Name of the RequestContext attribute for all views.
*/
private String requestContextAttribute;
/**
* Whether all request attributes should be added to the model prior to merging with
* the template.
*/
private boolean exposeRequestAttributes = false;
/**
* Whether all HttpSession attributes should be added to the model prior to merging
* with the template.
*/
private boolean exposeSessionAttributes = false;
/**
* Whether HttpServletRequest attributes are allowed to override (hide) controller
* generated model attributes of the same name.
*/
private boolean allowRequestOverride = false;
/**
* Whether to expose a RequestContext for use by Spring's macro library, under the
* name "springMacroRequestContext".
*/
private boolean exposeSpringMacroHelpers = true;
/**
* Whether HttpSession attributes are allowed to override (hide) controller generated
* model attributes of the same name.
*/
private boolean allowSessionOverride = false;
/** /**
* Well-known FreeMarker keys which are passed to FreeMarker's Configuration. * Well-known FreeMarker keys which are passed to FreeMarker's Configuration.
*/ */
@ -56,8 +141,62 @@ public class FreeMarkerProperties extends AbstractTemplateViewResolverProperties
*/ */
private boolean preferFileSystemAccess; private boolean preferFileSystemAccess;
public FreeMarkerProperties() { public void setEnabled(boolean enabled) {
super(DEFAULT_PREFIX, DEFAULT_SUFFIX); this.enabled = enabled;
}
public boolean isEnabled() {
return this.enabled;
}
public void setCheckTemplateLocation(boolean checkTemplateLocation) {
this.checkTemplateLocation = checkTemplateLocation;
}
public boolean isCheckTemplateLocation() {
return this.checkTemplateLocation;
}
public String[] getViewNames() {
return this.viewNames;
}
public void setViewNames(String[] viewNames) {
this.viewNames = viewNames;
}
public boolean isCache() {
return this.cache;
}
public void setCache(boolean cache) {
this.cache = cache;
}
public MimeType getContentType() {
if (this.contentType.getCharset() == null) {
Map<String, String> parameters = new LinkedHashMap<>();
parameters.put("charset", this.charset.name());
parameters.putAll(this.contentType.getParameters());
return new MimeType(this.contentType, parameters);
}
return this.contentType;
}
public void setContentType(MimeType contentType) {
this.contentType = contentType;
}
public Charset getCharset() {
return this.charset;
}
public String getCharsetName() {
return (this.charset != null) ? this.charset.name() : null;
}
public void setCharset(Charset charset) {
this.charset = charset;
} }
public Map<String, String> getSettings() { public Map<String, String> getSettings() {
@ -84,4 +223,96 @@ public class FreeMarkerProperties extends AbstractTemplateViewResolverProperties
this.preferFileSystemAccess = preferFileSystemAccess; this.preferFileSystemAccess = preferFileSystemAccess;
} }
public String getPrefix() {
return this.prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public String getSuffix() {
return this.suffix;
}
public void setSuffix(String suffix) {
this.suffix = suffix;
}
public String getRequestContextAttribute() {
return this.requestContextAttribute;
}
public void setRequestContextAttribute(String requestContextAttribute) {
this.requestContextAttribute = requestContextAttribute;
}
public boolean isExposeRequestAttributes() {
return this.exposeRequestAttributes;
}
public void setExposeRequestAttributes(boolean exposeRequestAttributes) {
this.exposeRequestAttributes = exposeRequestAttributes;
}
public boolean isExposeSessionAttributes() {
return this.exposeSessionAttributes;
}
public void setExposeSessionAttributes(boolean exposeSessionAttributes) {
this.exposeSessionAttributes = exposeSessionAttributes;
}
public boolean isAllowRequestOverride() {
return this.allowRequestOverride;
}
public void setAllowRequestOverride(boolean allowRequestOverride) {
this.allowRequestOverride = allowRequestOverride;
}
public boolean isAllowSessionOverride() {
return this.allowSessionOverride;
}
public void setAllowSessionOverride(boolean allowSessionOverride) {
this.allowSessionOverride = allowSessionOverride;
}
public boolean isExposeSpringMacroHelpers() {
return this.exposeSpringMacroHelpers;
}
public void setExposeSpringMacroHelpers(boolean exposeSpringMacroHelpers) {
this.exposeSpringMacroHelpers = exposeSpringMacroHelpers;
}
/**
* Apply the given properties to a {@link AbstractTemplateViewResolver}. Use Object in
* signature to avoid runtime dependency on MVC, which means that the template engine
* can be used in a non-web application.
* @param viewResolver the resolver to apply the properties to.
*/
public void applyToMvcViewResolver(Object viewResolver) {
Assert.isInstanceOf(AbstractTemplateViewResolver.class, viewResolver,
() -> "ViewResolver is not an instance of AbstractTemplateViewResolver :" + viewResolver);
AbstractTemplateViewResolver resolver = (AbstractTemplateViewResolver) viewResolver;
resolver.setPrefix(getPrefix());
resolver.setSuffix(getSuffix());
resolver.setCache(isCache());
if (getContentType() != null) {
resolver.setContentType(getContentType().toString());
}
resolver.setViewNames(getViewNames());
resolver.setExposeRequestAttributes(isExposeRequestAttributes());
resolver.setAllowRequestOverride(isAllowRequestOverride());
resolver.setAllowSessionOverride(isAllowSessionOverride());
resolver.setExposeSessionAttributes(isExposeSessionAttributes());
resolver.setExposeSpringMacroHelpers(isExposeSpringMacroHelpers());
resolver.setRequestContextAttribute(getRequestContextAttribute());
// The resolver usually acts as a fallback resolver (e.g. like a
// InternalResourceViewResolver) so it needs to have low precedence
resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 5);
}
} }

View File

@ -16,12 +16,19 @@
package org.springframework.boot.autoconfigure.groovy.template; package org.springframework.boot.autoconfigure.groovy.template;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap;
import java.util.Locale; import java.util.Locale;
import java.util.Map;
import groovy.text.markup.BaseTemplate; import groovy.text.markup.BaseTemplate;
import org.springframework.boot.autoconfigure.template.AbstractTemplateViewResolverProperties;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.Ordered;
import org.springframework.util.Assert;
import org.springframework.util.MimeType;
import org.springframework.web.servlet.view.AbstractTemplateViewResolver;
/** /**
* {@link ConfigurationProperties @ConfigurationProperties} for configuring Groovy * {@link ConfigurationProperties @ConfigurationProperties} for configuring Groovy
@ -32,7 +39,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
* @since 1.1.0 * @since 1.1.0
*/ */
@ConfigurationProperties("spring.groovy.template") @ConfigurationProperties("spring.groovy.template")
public class GroovyTemplateProperties extends AbstractTemplateViewResolverProperties { public class GroovyTemplateProperties {
public static final String DEFAULT_RESOURCE_LOADER_PATH = "classpath:/templates/"; public static final String DEFAULT_RESOURCE_LOADER_PATH = "classpath:/templates/";
@ -42,6 +49,85 @@ public class GroovyTemplateProperties extends AbstractTemplateViewResolverProper
public static final String DEFAULT_REQUEST_CONTEXT_ATTRIBUTE = "spring"; public static final String DEFAULT_REQUEST_CONTEXT_ATTRIBUTE = "spring";
private static final MimeType DEFAULT_CONTENT_TYPE = MimeType.valueOf("text/html");
private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
/**
* Whether to enable MVC view resolution for this technology.
*/
private boolean enabled = true;
/**
* Whether to enable template caching.
*/
private boolean cache;
/**
* Content-Type value.
*/
private MimeType contentType = DEFAULT_CONTENT_TYPE;
/**
* Template encoding.
*/
private Charset charset = DEFAULT_CHARSET;
/**
* View names that can be resolved.
*/
private String[] viewNames;
/**
* Whether to check that the templates location exists.
*/
private boolean checkTemplateLocation = true;
/**
* Prefix that gets prepended to view names when building a URL.
*/
private String prefix = DEFAULT_PREFIX;
/**
* Suffix that gets appended to view names when building a URL.
*/
private String suffix = DEFAULT_SUFFIX;
/**
* Name of the RequestContext attribute for all views.
*/
private String requestContextAttribute = DEFAULT_REQUEST_CONTEXT_ATTRIBUTE;
/**
* Whether all request attributes should be added to the model prior to merging with
* the template.
*/
private boolean exposeRequestAttributes = false;
/**
* Whether all HttpSession attributes should be added to the model prior to merging
* with the template.
*/
private boolean exposeSessionAttributes = false;
/**
* Whether HttpServletRequest attributes are allowed to override (hide) controller
* generated model attributes of the same name.
*/
private boolean allowRequestOverride = false;
/**
* Whether to expose a RequestContext for use by Spring's macro library, under the
* name "springMacroRequestContext".
*/
private boolean exposeSpringMacroHelpers = true;
/**
* Whether HttpSession attributes are allowed to override (hide) controller generated
* model attributes of the same name.
*/
private boolean allowSessionOverride = false;
/** /**
* Whether models that are assignable to CharSequence are escaped automatically. * Whether models that are assignable to CharSequence are escaped automatically.
*/ */
@ -98,9 +184,62 @@ public class GroovyTemplateProperties extends AbstractTemplateViewResolverProper
*/ */
private boolean useDoubleQuotes; private boolean useDoubleQuotes;
public GroovyTemplateProperties() { public boolean isEnabled() {
super(DEFAULT_PREFIX, DEFAULT_SUFFIX); return this.enabled;
setRequestContextAttribute(DEFAULT_REQUEST_CONTEXT_ATTRIBUTE); }
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public boolean isCheckTemplateLocation() {
return this.checkTemplateLocation;
}
public void setCheckTemplateLocation(boolean checkTemplateLocation) {
this.checkTemplateLocation = checkTemplateLocation;
}
public String[] getViewNames() {
return this.viewNames;
}
public void setViewNames(String[] viewNames) {
this.viewNames = viewNames;
}
public boolean isCache() {
return this.cache;
}
public void setCache(boolean cache) {
this.cache = cache;
}
public MimeType getContentType() {
if (this.contentType.getCharset() == null) {
Map<String, String> parameters = new LinkedHashMap<>();
parameters.put("charset", this.charset.name());
parameters.putAll(this.contentType.getParameters());
return new MimeType(this.contentType, parameters);
}
return this.contentType;
}
public void setContentType(MimeType contentType) {
this.contentType = contentType;
}
public Charset getCharset() {
return this.charset;
}
public String getCharsetName() {
return (this.charset != null) ? this.charset.name() : null;
}
public void setCharset(Charset charset) {
this.charset = charset;
} }
public boolean isAutoEscape() { public boolean isAutoEscape() {
@ -191,4 +330,96 @@ public class GroovyTemplateProperties extends AbstractTemplateViewResolverProper
this.useDoubleQuotes = useDoubleQuotes; this.useDoubleQuotes = useDoubleQuotes;
} }
public String getPrefix() {
return this.prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public String getSuffix() {
return this.suffix;
}
public void setSuffix(String suffix) {
this.suffix = suffix;
}
public String getRequestContextAttribute() {
return this.requestContextAttribute;
}
public void setRequestContextAttribute(String requestContextAttribute) {
this.requestContextAttribute = requestContextAttribute;
}
public boolean isExposeRequestAttributes() {
return this.exposeRequestAttributes;
}
public void setExposeRequestAttributes(boolean exposeRequestAttributes) {
this.exposeRequestAttributes = exposeRequestAttributes;
}
public boolean isExposeSessionAttributes() {
return this.exposeSessionAttributes;
}
public void setExposeSessionAttributes(boolean exposeSessionAttributes) {
this.exposeSessionAttributes = exposeSessionAttributes;
}
public boolean isAllowRequestOverride() {
return this.allowRequestOverride;
}
public void setAllowRequestOverride(boolean allowRequestOverride) {
this.allowRequestOverride = allowRequestOverride;
}
public boolean isAllowSessionOverride() {
return this.allowSessionOverride;
}
public void setAllowSessionOverride(boolean allowSessionOverride) {
this.allowSessionOverride = allowSessionOverride;
}
public boolean isExposeSpringMacroHelpers() {
return this.exposeSpringMacroHelpers;
}
public void setExposeSpringMacroHelpers(boolean exposeSpringMacroHelpers) {
this.exposeSpringMacroHelpers = exposeSpringMacroHelpers;
}
/**
* Apply the given properties to a {@link AbstractTemplateViewResolver}. Use Object in
* signature to avoid runtime dependency on MVC, which means that the template engine
* can be used in a non-web application.
* @param viewResolver the resolver to apply the properties to.
*/
public void applyToMvcViewResolver(Object viewResolver) {
Assert.isInstanceOf(AbstractTemplateViewResolver.class, viewResolver,
() -> "ViewResolver is not an instance of AbstractTemplateViewResolver :" + viewResolver);
AbstractTemplateViewResolver resolver = (AbstractTemplateViewResolver) viewResolver;
resolver.setPrefix(getPrefix());
resolver.setSuffix(getSuffix());
resolver.setCache(isCache());
if (getContentType() != null) {
resolver.setContentType(getContentType().toString());
}
resolver.setViewNames(getViewNames());
resolver.setExposeRequestAttributes(isExposeRequestAttributes());
resolver.setAllowRequestOverride(isAllowRequestOverride());
resolver.setAllowSessionOverride(isAllowSessionOverride());
resolver.setExposeSessionAttributes(isExposeSessionAttributes());
resolver.setExposeSpringMacroHelpers(isExposeSpringMacroHelpers());
resolver.setRequestContextAttribute(getRequestContextAttribute());
// The resolver usually acts as a fallback resolver (e.g. like a
// InternalResourceViewResolver) so it needs to have low precedence
resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 5);
}
} }

View File

@ -1,175 +0,0 @@
/*
* Copyright 2012-present 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.autoconfigure.template;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.Ordered;
import org.springframework.util.Assert;
import org.springframework.web.servlet.view.AbstractTemplateViewResolver;
/**
* Base class for {@link ConfigurationProperties @ConfigurationProperties} of a
* {@link AbstractTemplateViewResolver}.
*
* @author Andy Wilkinson
* @since 1.1.0
*/
public abstract class AbstractTemplateViewResolverProperties extends AbstractViewResolverProperties {
/**
* Prefix that gets prepended to view names when building a URL.
*/
private String prefix;
/**
* Suffix that gets appended to view names when building a URL.
*/
private String suffix;
/**
* Name of the RequestContext attribute for all views.
*/
private String requestContextAttribute;
/**
* Whether all request attributes should be added to the model prior to merging with
* the template.
*/
private boolean exposeRequestAttributes = false;
/**
* Whether all HttpSession attributes should be added to the model prior to merging
* with the template.
*/
private boolean exposeSessionAttributes = false;
/**
* Whether HttpServletRequest attributes are allowed to override (hide) controller
* generated model attributes of the same name.
*/
private boolean allowRequestOverride = false;
/**
* Whether to expose a RequestContext for use by Spring's macro library, under the
* name "springMacroRequestContext".
*/
private boolean exposeSpringMacroHelpers = true;
/**
* Whether HttpSession attributes are allowed to override (hide) controller generated
* model attributes of the same name.
*/
private boolean allowSessionOverride = false;
protected AbstractTemplateViewResolverProperties(String defaultPrefix, String defaultSuffix) {
this.prefix = defaultPrefix;
this.suffix = defaultSuffix;
}
public String getPrefix() {
return this.prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public String getSuffix() {
return this.suffix;
}
public void setSuffix(String suffix) {
this.suffix = suffix;
}
public String getRequestContextAttribute() {
return this.requestContextAttribute;
}
public void setRequestContextAttribute(String requestContextAttribute) {
this.requestContextAttribute = requestContextAttribute;
}
public boolean isExposeRequestAttributes() {
return this.exposeRequestAttributes;
}
public void setExposeRequestAttributes(boolean exposeRequestAttributes) {
this.exposeRequestAttributes = exposeRequestAttributes;
}
public boolean isExposeSessionAttributes() {
return this.exposeSessionAttributes;
}
public void setExposeSessionAttributes(boolean exposeSessionAttributes) {
this.exposeSessionAttributes = exposeSessionAttributes;
}
public boolean isAllowRequestOverride() {
return this.allowRequestOverride;
}
public void setAllowRequestOverride(boolean allowRequestOverride) {
this.allowRequestOverride = allowRequestOverride;
}
public boolean isAllowSessionOverride() {
return this.allowSessionOverride;
}
public void setAllowSessionOverride(boolean allowSessionOverride) {
this.allowSessionOverride = allowSessionOverride;
}
public boolean isExposeSpringMacroHelpers() {
return this.exposeSpringMacroHelpers;
}
public void setExposeSpringMacroHelpers(boolean exposeSpringMacroHelpers) {
this.exposeSpringMacroHelpers = exposeSpringMacroHelpers;
}
/**
* Apply the given properties to a {@link AbstractTemplateViewResolver}. Use Object in
* signature to avoid runtime dependency on MVC, which means that the template engine
* can be used in a non-web application.
* @param viewResolver the resolver to apply the properties to.
*/
public void applyToMvcViewResolver(Object viewResolver) {
Assert.isInstanceOf(AbstractTemplateViewResolver.class, viewResolver,
() -> "ViewResolver is not an instance of AbstractTemplateViewResolver :" + viewResolver);
AbstractTemplateViewResolver resolver = (AbstractTemplateViewResolver) viewResolver;
resolver.setPrefix(getPrefix());
resolver.setSuffix(getSuffix());
resolver.setCache(isCache());
if (getContentType() != null) {
resolver.setContentType(getContentType().toString());
}
resolver.setViewNames(getViewNames());
resolver.setExposeRequestAttributes(isExposeRequestAttributes());
resolver.setAllowRequestOverride(isAllowRequestOverride());
resolver.setAllowSessionOverride(isAllowSessionOverride());
resolver.setExposeSessionAttributes(isExposeSessionAttributes());
resolver.setExposeSpringMacroHelpers(isExposeSpringMacroHelpers());
resolver.setRequestContextAttribute(getRequestContextAttribute());
// The resolver usually acts as a fallback resolver (e.g. like a
// InternalResourceViewResolver) so it needs to have low precedence
resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 5);
}
}

View File

@ -1,131 +0,0 @@
/*
* Copyright 2012-present 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.autoconfigure.template;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap;
import java.util.Map;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.util.MimeType;
import org.springframework.web.servlet.ViewResolver;
/**
* Base class for {@link ConfigurationProperties @ConfigurationProperties} of a
* {@link ViewResolver}.
*
* @author Andy Wilkinson
* @author Stephane Nicoll
* @since 1.2.0
* @see AbstractTemplateViewResolverProperties
*/
public abstract class AbstractViewResolverProperties {
private static final MimeType DEFAULT_CONTENT_TYPE = MimeType.valueOf("text/html");
private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
/**
* Whether to enable MVC view resolution for this technology.
*/
private boolean enabled = true;
/**
* Whether to enable template caching.
*/
private boolean cache;
/**
* Content-Type value.
*/
private MimeType contentType = DEFAULT_CONTENT_TYPE;
/**
* Template encoding.
*/
private Charset charset = DEFAULT_CHARSET;
/**
* View names that can be resolved.
*/
private String[] viewNames;
/**
* Whether to check that the templates location exists.
*/
private boolean checkTemplateLocation = true;
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public boolean isEnabled() {
return this.enabled;
}
public void setCheckTemplateLocation(boolean checkTemplateLocation) {
this.checkTemplateLocation = checkTemplateLocation;
}
public boolean isCheckTemplateLocation() {
return this.checkTemplateLocation;
}
public String[] getViewNames() {
return this.viewNames;
}
public void setViewNames(String[] viewNames) {
this.viewNames = viewNames;
}
public boolean isCache() {
return this.cache;
}
public void setCache(boolean cache) {
this.cache = cache;
}
public MimeType getContentType() {
if (this.contentType.getCharset() == null) {
Map<String, String> parameters = new LinkedHashMap<>();
parameters.put("charset", this.charset.name());
parameters.putAll(this.contentType.getParameters());
return new MimeType(this.contentType, parameters);
}
return this.contentType;
}
public void setContentType(MimeType contentType) {
this.contentType = contentType;
}
public Charset getCharset() {
return this.charset;
}
public String getCharsetName() {
return (this.charset != null) ? this.charset.name() : null;
}
public void setCharset(Charset charset) {
this.charset = charset;
}
}

View File

@ -1,8 +1,7 @@
org.springframework.aot.hint.RuntimeHintsRegistrar=\ org.springframework.aot.hint.RuntimeHintsRegistrar=\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider$FreeMarkerTemplateAvailabilityRuntimeHints,\ org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider$FreeMarkerTemplateAvailabilityRuntimeHints,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider$GroovyTemplateAvailabilityRuntimeHints,\ org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider$GroovyTemplateAvailabilityRuntimeHints,\
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$JacksonAutoConfigurationRuntimeHints,\ org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$JacksonAutoConfigurationRuntimeHints
org.springframework.boot.autoconfigure.template.TemplateRuntimeHints
org.springframework.beans.factory.aot.BeanRegistrationAotProcessor=\ org.springframework.beans.factory.aot.BeanRegistrationAotProcessor=\
org.springframework.boot.autoconfigure.flyway.ResourceProviderCustomizerBeanRegistrationAotProcessor org.springframework.boot.autoconfigure.flyway.ResourceProviderCustomizerBeanRegistrationAotProcessor

View File

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.boot.autoconfigure.template; package org.springframework.boot.autoconfigure.freemarker;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@ -25,34 +25,34 @@ import org.springframework.util.MimeTypeUtils;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
/** /**
* Tests for {@link AbstractViewResolverProperties}. * Tests for {@link FreeMarkerProperties}.
* *
* @author Stephane Nicoll * @author Stephane Nicoll
*/ */
class ViewResolverPropertiesTests { class FreeMarkerPropertiesTests {
@Test @Test
void defaultContentType() { void defaultContentType() {
assertThat(new ViewResolverProperties().getContentType()).hasToString("text/html;charset=UTF-8"); assertThat(new FreeMarkerProperties().getContentType()).hasToString("text/html;charset=UTF-8");
} }
@Test @Test
void customContentTypeDefaultCharset() { void customContentTypeDefaultCharset() {
ViewResolverProperties properties = new ViewResolverProperties(); FreeMarkerProperties properties = new FreeMarkerProperties();
properties.setContentType(MimeTypeUtils.parseMimeType("text/plain")); properties.setContentType(MimeTypeUtils.parseMimeType("text/plain"));
assertThat(properties.getContentType()).hasToString("text/plain;charset=UTF-8"); assertThat(properties.getContentType()).hasToString("text/plain;charset=UTF-8");
} }
@Test @Test
void defaultContentTypeCustomCharset() { void defaultContentTypeCustomCharset() {
ViewResolverProperties properties = new ViewResolverProperties(); FreeMarkerProperties properties = new FreeMarkerProperties();
properties.setCharset(StandardCharsets.UTF_16); properties.setCharset(StandardCharsets.UTF_16);
assertThat(properties.getContentType()).hasToString("text/html;charset=UTF-16"); assertThat(properties.getContentType()).hasToString("text/html;charset=UTF-16");
} }
@Test @Test
void customContentTypeCustomCharset() { void customContentTypeCustomCharset() {
ViewResolverProperties properties = new ViewResolverProperties(); FreeMarkerProperties properties = new FreeMarkerProperties();
properties.setContentType(MimeTypeUtils.parseMimeType("text/plain")); properties.setContentType(MimeTypeUtils.parseMimeType("text/plain"));
properties.setCharset(StandardCharsets.UTF_16); properties.setCharset(StandardCharsets.UTF_16);
assertThat(properties.getContentType()).hasToString("text/plain;charset=UTF-16"); assertThat(properties.getContentType()).hasToString("text/plain;charset=UTF-16");
@ -60,14 +60,10 @@ class ViewResolverPropertiesTests {
@Test @Test
void customContentTypeWithPropertyAndCustomCharset() { void customContentTypeWithPropertyAndCustomCharset() {
ViewResolverProperties properties = new ViewResolverProperties(); FreeMarkerProperties properties = new FreeMarkerProperties();
properties.setContentType(MimeTypeUtils.parseMimeType("text/plain;foo=bar")); properties.setContentType(MimeTypeUtils.parseMimeType("text/plain;foo=bar"));
properties.setCharset(StandardCharsets.UTF_16); properties.setCharset(StandardCharsets.UTF_16);
assertThat(properties.getContentType()).hasToString("text/plain;charset=UTF-16;foo=bar"); assertThat(properties.getContentType()).hasToString("text/plain;charset=UTF-16;foo=bar");
} }
static class ViewResolverProperties extends AbstractViewResolverProperties {
}
} }

View File

@ -0,0 +1,69 @@
/*
* Copyright 2012-present 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.autoconfigure.groovy.template;
import java.nio.charset.StandardCharsets;
import org.junit.jupiter.api.Test;
import org.springframework.util.MimeTypeUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link GroovyTemplateProperties}.
*
* @author Stephane Nicoll
*/
class GroovyTemplatePropertiesTests {
@Test
void defaultContentType() {
assertThat(new GroovyTemplateProperties().getContentType()).hasToString("text/html;charset=UTF-8");
}
@Test
void customContentTypeDefaultCharset() {
GroovyTemplateProperties properties = new GroovyTemplateProperties();
properties.setContentType(MimeTypeUtils.parseMimeType("text/plain"));
assertThat(properties.getContentType()).hasToString("text/plain;charset=UTF-8");
}
@Test
void defaultContentTypeCustomCharset() {
GroovyTemplateProperties properties = new GroovyTemplateProperties();
properties.setCharset(StandardCharsets.UTF_16);
assertThat(properties.getContentType()).hasToString("text/html;charset=UTF-16");
}
@Test
void customContentTypeCustomCharset() {
GroovyTemplateProperties properties = new GroovyTemplateProperties();
properties.setContentType(MimeTypeUtils.parseMimeType("text/plain"));
properties.setCharset(StandardCharsets.UTF_16);
assertThat(properties.getContentType()).hasToString("text/plain;charset=UTF-16");
}
@Test
void customContentTypeWithPropertyAndCustomCharset() {
GroovyTemplateProperties properties = new GroovyTemplateProperties();
properties.setContentType(MimeTypeUtils.parseMimeType("text/plain;foo=bar"));
properties.setCharset(StandardCharsets.UTF_16);
assertThat(properties.getContentType()).hasToString("text/plain;charset=UTF-16;foo=bar");
}
}

View File

@ -3,3 +3,6 @@ org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingP
org.springframework.beans.factory.aot.BeanRegistrationExcludeFilter=\ org.springframework.beans.factory.aot.BeanRegistrationExcludeFilter=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer
org.springframework.aot.hint.RuntimeHintsRegistrar=\
org.springframework.boot.autoconfigure.template.TemplateRuntimeHints