Add property for media types of reactive Mustache views

Closes gh-28858
pull/30406/head
Andy Wilkinson 3 years ago
parent 3a5a748ec0
commit b787ea4802

@ -18,9 +18,11 @@ package org.springframework.boot.autoconfigure.mustache;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.List;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.DeprecatedConfigurationProperty; import org.springframework.boot.context.properties.DeprecatedConfigurationProperty;
import org.springframework.http.MediaType;
import org.springframework.util.MimeType; import org.springframework.util.MimeType;
/** /**
@ -42,6 +44,8 @@ public class MustacheProperties {
private final Servlet servlet = new Servlet(); private final Servlet servlet = new Servlet();
private final Reactive reactive = new Reactive();
/** /**
* View names that can be resolved. * View names that can be resolved.
*/ */
@ -81,6 +85,10 @@ public class MustacheProperties {
return this.servlet; return this.servlet;
} }
public Reactive getReactive() {
return this.reactive;
}
public String getPrefix() { public String getPrefix() {
return this.prefix; return this.prefix;
} }
@ -318,4 +326,21 @@ public class MustacheProperties {
} }
public static class Reactive {
/**
* Media types supported by Mustache views.
*/
private List<MediaType> mediaTypes;
public List<MediaType> getMediaTypes() {
return this.mediaTypes;
}
public void setMediaTypes(List<MediaType> mediaTypes) {
this.mediaTypes = mediaTypes;
}
}
} }

@ -22,6 +22,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.boot.web.reactive.result.view.MustacheViewResolver; import org.springframework.boot.web.reactive.result.view.MustacheViewResolver;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -36,11 +37,13 @@ class MustacheReactiveWebConfiguration {
@ConditionalOnProperty(prefix = "spring.mustache", name = "enabled", matchIfMissing = true) @ConditionalOnProperty(prefix = "spring.mustache", name = "enabled", matchIfMissing = true)
MustacheViewResolver mustacheViewResolver(Compiler mustacheCompiler, MustacheProperties mustache) { MustacheViewResolver mustacheViewResolver(Compiler mustacheCompiler, MustacheProperties mustache) {
MustacheViewResolver resolver = new MustacheViewResolver(mustacheCompiler); MustacheViewResolver resolver = new MustacheViewResolver(mustacheCompiler);
resolver.setPrefix(mustache.getPrefix()); PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
resolver.setSuffix(mustache.getSuffix()); map.from(mustache::getPrefix).to(resolver::setPrefix);
resolver.setViewNames(mustache.getViewNames()); map.from(mustache::getSuffix).to(resolver::setSuffix);
resolver.setRequestContextAttribute(mustache.getRequestContextAttribute()); map.from(mustache::getViewNames).to(resolver::setViewNames);
resolver.setCharset(mustache.getCharsetName()); map.from(mustache::getRequestContextAttribute).to(resolver::setRequestContextAttribute);
map.from(mustache::getCharsetName).to(resolver::setCharset);
map.from(mustache.getReactive()::getMediaTypes).to(resolver::setSupportedMediaTypes);
resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 10); resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 10);
return resolver; return resolver;
} }

@ -1627,6 +1627,10 @@
"name": "spring.mustache.prefix", "name": "spring.mustache.prefix",
"defaultValue": "classpath:/templates/" "defaultValue": "classpath:/templates/"
}, },
{
"name": "spring.mustache.reactive.media-types",
"defaultValue": "text/html;charset=UTF-8"
},
{ {
"name": "spring.mustache.suffix", "name": "spring.mustache.suffix",
"defaultValue": ".mustache" "defaultValue": ".mustache"

@ -16,6 +16,7 @@
package org.springframework.boot.autoconfigure.mustache; package org.springframework.boot.autoconfigure.mustache;
import java.util.Arrays;
import java.util.function.Supplier; import java.util.function.Supplier;
import com.samskivert.mustache.Mustache; import com.samskivert.mustache.Mustache;
@ -31,6 +32,7 @@ import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.boot.web.servlet.view.MustacheViewResolver; import org.springframework.boot.web.servlet.view.MustacheViewResolver;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ -133,6 +135,8 @@ class MustacheAutoConfigurationTests {
assertThat(viewResolver).extracting("prefix").isEqualTo("classpath:/templates/"); assertThat(viewResolver).extracting("prefix").isEqualTo("classpath:/templates/");
assertThat(viewResolver).extracting("requestContextAttribute").isNull(); assertThat(viewResolver).extracting("requestContextAttribute").isNull();
assertThat(viewResolver).extracting("suffix").isEqualTo(".mustache"); assertThat(viewResolver).extracting("suffix").isEqualTo(".mustache");
assertThat(viewResolver.getSupportedMediaTypes())
.containsExactly(MediaType.parseMediaType("text/html;charset=UTF-8"));
}); });
} }
@ -238,6 +242,14 @@ class MustacheAutoConfigurationTests {
assertViewResolverProperty(kind, "spring.mustache.suffix=.tache", "suffix", ".tache"); assertViewResolverProperty(kind, "spring.mustache.suffix=.tache", "suffix", ".tache");
} }
@Test
void mediaTypesCanBeCustomizedOnReactiveViewResolver() {
assertViewResolverProperty(ViewResolverKind.REACTIVE,
"spring.mustache.reactive.media-types=text/xml;charset=UTF-8,text/plain;charset=UTF-16", "mediaTypes",
Arrays.asList(MediaType.parseMediaType("text/xml;charset=UTF-8"),
MediaType.parseMediaType("text/plain;charset=UTF-16")));
}
private void assertViewResolverProperty(ViewResolverKind kind, String property, String field, private void assertViewResolverProperty(ViewResolverKind kind, String property, String field,
Object expectedValue) { Object expectedValue) {
kind.runner().withConfiguration(AutoConfigurations.of(MustacheAutoConfiguration.class)) kind.runner().withConfiguration(AutoConfigurations.of(MustacheAutoConfiguration.class))

Loading…
Cancel
Save