Refine Mustache support
Refine Mustache support to provide a cleaner separation between the reactive and servlet implementations. The views have now moved to the `spring-boot` project and the auto-configuration has been split into two distinct `@Imports` to save needing full package declarations. See gh-8941
This commit is contained in:
parent
06558675bb
commit
1ad318d8a6
|
|
@ -28,10 +28,10 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplicat
|
||||||
import org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration;
|
import org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration;
|
import org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration;
|
import org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.mustache.servlet.MustacheViewResolver;
|
|
||||||
import org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration;
|
import org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
|
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
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.mobile.device.view.LiteDeviceDelegatingViewResolver;
|
import org.springframework.mobile.device.view.LiteDeviceDelegatingViewResolver;
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ import javax.annotation.PostConstruct;
|
||||||
|
|
||||||
import com.samskivert.mustache.Mustache;
|
import com.samskivert.mustache.Mustache;
|
||||||
import com.samskivert.mustache.Mustache.Collector;
|
import com.samskivert.mustache.Mustache.Collector;
|
||||||
import com.samskivert.mustache.Mustache.Compiler;
|
|
||||||
import com.samskivert.mustache.Mustache.TemplateLoader;
|
import com.samskivert.mustache.Mustache.TemplateLoader;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
@ -28,15 +27,12 @@ import org.apache.commons.logging.LogFactory;
|
||||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
|
|
||||||
import org.springframework.boot.autoconfigure.mustache.servlet.MustacheViewResolver;
|
|
||||||
import org.springframework.boot.autoconfigure.template.TemplateLocation;
|
import org.springframework.boot.autoconfigure.template.TemplateLocation;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
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.core.Ordered;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -49,6 +45,7 @@ import org.springframework.core.env.Environment;
|
||||||
@Configuration
|
@Configuration
|
||||||
@ConditionalOnClass(Mustache.class)
|
@ConditionalOnClass(Mustache.class)
|
||||||
@EnableConfigurationProperties(MustacheProperties.class)
|
@EnableConfigurationProperties(MustacheProperties.class)
|
||||||
|
@Import({ MustacheServletWebConfiguration.class, MustacheReactiveWebConfiguration.class })
|
||||||
public class MustacheAutoConfiguration {
|
public class MustacheAutoConfiguration {
|
||||||
|
|
||||||
private static final Log logger = LogFactory.getLog(MustacheAutoConfiguration.class);
|
private static final Log logger = LogFactory.getLog(MustacheAutoConfiguration.class);
|
||||||
|
|
@ -101,56 +98,4 @@ public class MustacheAutoConfiguration {
|
||||||
return loader;
|
return loader;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@ConditionalOnWebApplication(type = Type.SERVLET)
|
|
||||||
protected static class MustacheWebConfiguration {
|
|
||||||
|
|
||||||
private final MustacheProperties mustache;
|
|
||||||
|
|
||||||
protected MustacheWebConfiguration(MustacheProperties mustache) {
|
|
||||||
this.mustache = mustache;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
@ConditionalOnMissingBean(MustacheViewResolver.class)
|
|
||||||
public MustacheViewResolver mustacheViewResolver(Compiler mustacheCompiler) {
|
|
||||||
MustacheViewResolver resolver = new MustacheViewResolver(mustacheCompiler);
|
|
||||||
this.mustache.applyToViewResolver(resolver);
|
|
||||||
resolver.setCharset(this.mustache.getCharsetName());
|
|
||||||
resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 10);
|
|
||||||
return resolver;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@ConditionalOnWebApplication(type = Type.REACTIVE)
|
|
||||||
protected static class MustacheReactiveWebConfiguration {
|
|
||||||
|
|
||||||
private final MustacheProperties mustache;
|
|
||||||
|
|
||||||
protected MustacheReactiveWebConfiguration(MustacheProperties mustache) {
|
|
||||||
this.mustache = mustache;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
@ConditionalOnMissingBean(org.springframework.boot.autoconfigure
|
|
||||||
.mustache.reactive.MustacheViewResolver.class)
|
|
||||||
public org.springframework.boot.autoconfigure
|
|
||||||
.mustache.reactive.MustacheViewResolver mustacheViewResolver(Compiler mustacheCompiler) {
|
|
||||||
org.springframework.boot.autoconfigure
|
|
||||||
.mustache.reactive.MustacheViewResolver resolver
|
|
||||||
= new org.springframework.boot.autoconfigure
|
|
||||||
.mustache.reactive.MustacheViewResolver(mustacheCompiler);
|
|
||||||
resolver.setPrefix(this.mustache.getPrefix());
|
|
||||||
resolver.setSuffix(this.mustache.getSuffix());
|
|
||||||
resolver.setViewNames(this.mustache.getViewNames());
|
|
||||||
resolver.setRequestContextAttribute(this.mustache.getRequestContextAttribute());
|
|
||||||
resolver.setCharset(this.mustache.getCharsetName());
|
|
||||||
resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 10);
|
|
||||||
return resolver;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2017 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
|
||||||
|
*
|
||||||
|
* http://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.mustache;
|
||||||
|
|
||||||
|
import com.samskivert.mustache.Mustache.Compiler;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
|
||||||
|
import org.springframework.boot.web.reactive.result.view.MustacheViewResolver;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.core.Ordered;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ConditionalOnWebApplication(type = Type.REACTIVE)
|
||||||
|
class MustacheReactiveWebConfiguration {
|
||||||
|
|
||||||
|
private final MustacheProperties mustache;
|
||||||
|
|
||||||
|
protected MustacheReactiveWebConfiguration(MustacheProperties mustache) {
|
||||||
|
this.mustache = mustache;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean(MustacheViewResolver.class)
|
||||||
|
public MustacheViewResolver mustacheViewResolver(Compiler mustacheCompiler) {
|
||||||
|
MustacheViewResolver resolver = new MustacheViewResolver(mustacheCompiler);
|
||||||
|
resolver.setPrefix(this.mustache.getPrefix());
|
||||||
|
resolver.setSuffix(this.mustache.getSuffix());
|
||||||
|
resolver.setViewNames(this.mustache.getViewNames());
|
||||||
|
resolver.setRequestContextAttribute(this.mustache.getRequestContextAttribute());
|
||||||
|
resolver.setCharset(this.mustache.getCharsetName());
|
||||||
|
resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 10);
|
||||||
|
return resolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -20,6 +20,7 @@ import java.io.InputStreamReader;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
|
|
||||||
import com.samskivert.mustache.Mustache;
|
import com.samskivert.mustache.Mustache;
|
||||||
|
import com.samskivert.mustache.Mustache.Compiler;
|
||||||
import com.samskivert.mustache.Mustache.TemplateLoader;
|
import com.samskivert.mustache.Mustache.TemplateLoader;
|
||||||
|
|
||||||
import org.springframework.context.ResourceLoaderAware;
|
import org.springframework.context.ResourceLoaderAware;
|
||||||
|
|
@ -30,8 +31,8 @@ import org.springframework.core.io.ResourceLoader;
|
||||||
/**
|
/**
|
||||||
* Mustache TemplateLoader implementation that uses a prefix, suffix and the Spring
|
* Mustache TemplateLoader implementation that uses a prefix, suffix and the Spring
|
||||||
* Resource abstraction to load a template from a file, classpath, URL etc. A
|
* Resource abstraction to load a template from a file, classpath, URL etc. A
|
||||||
* TemplateLoader is needed in the Compiler when you want to render partials (i.e.
|
* {@link TemplateLoader} is needed in the {@link Compiler} when you want to render
|
||||||
* tiles-like features).
|
* partials (i.e. tiles-like features).
|
||||||
*
|
*
|
||||||
* @author Dave Syer
|
* @author Dave Syer
|
||||||
* @since 1.2.2
|
* @since 1.2.2
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2017 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
|
||||||
|
*
|
||||||
|
* http://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.mustache;
|
||||||
|
|
||||||
|
import com.samskivert.mustache.Mustache.Compiler;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
|
||||||
|
import org.springframework.boot.web.servlet.view.MustacheViewResolver;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.core.Ordered;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ConditionalOnWebApplication(type = Type.SERVLET)
|
||||||
|
class MustacheServletWebConfiguration {
|
||||||
|
|
||||||
|
private final MustacheProperties mustache;
|
||||||
|
|
||||||
|
protected MustacheServletWebConfiguration(MustacheProperties mustache) {
|
||||||
|
this.mustache = mustache;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean(MustacheViewResolver.class)
|
||||||
|
public MustacheViewResolver mustacheViewResolver(Compiler mustacheCompiler) {
|
||||||
|
MustacheViewResolver resolver = new MustacheViewResolver(mustacheCompiler);
|
||||||
|
this.mustache.applyToViewResolver(resolver);
|
||||||
|
resolver.setCharset(this.mustache.getCharsetName());
|
||||||
|
resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 10);
|
||||||
|
return resolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -34,10 +34,10 @@ import org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfigura
|
||||||
import org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration;
|
import org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration;
|
import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration;
|
import org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.mustache.servlet.MustacheViewResolver;
|
|
||||||
import org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration;
|
import org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
|
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
|
||||||
import org.springframework.boot.test.util.EnvironmentTestUtils;
|
import org.springframework.boot.test.util.EnvironmentTestUtils;
|
||||||
|
import org.springframework.boot.web.servlet.view.MustacheViewResolver;
|
||||||
import org.springframework.core.Ordered;
|
import org.springframework.core.Ordered;
|
||||||
import org.springframework.mobile.device.view.LiteDeviceDelegatingViewResolver;
|
import org.springframework.mobile.device.view.LiteDeviceDelegatingViewResolver;
|
||||||
import org.springframework.mock.web.MockServletContext;
|
import org.springframework.mock.web.MockServletContext;
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.mustache.reactive;
|
package org.springframework.boot.autoconfigure.mustache;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
|
|
@ -26,13 +26,13 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.WebApplicationType;
|
import org.springframework.boot.WebApplicationType;
|
||||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration;
|
|
||||||
import org.springframework.boot.autoconfigure.mustache.MustacheResourceTemplateLoader;
|
|
||||||
import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration;
|
import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerAutoConfiguration;
|
import org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration;
|
import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||||
|
import org.springframework.boot.web.reactive.result.view.MustacheView;
|
||||||
|
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;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
@ -51,34 +51,30 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||||
* @author Brian Clozel
|
* @author Brian Clozel
|
||||||
*/
|
*/
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT,
|
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = "spring.main.web-application-type=reactive")
|
||||||
properties = "spring.main.web-application-type=reactive")
|
public class MustacheAutoConfigurationReactiveIntegrationTests {
|
||||||
public class MustacheWebIntegrationTests {
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private WebTestClient client;
|
private WebTestClient client;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testHomePage() throws Exception {
|
public void testHomePage() throws Exception {
|
||||||
String result = (String) this.client.get().uri("/").exchange()
|
String result = this.client.get().uri("/").exchange().expectStatus().isOk()
|
||||||
.expectStatus().isOk()
|
|
||||||
.expectBody(String.class).returnResult().getResponseBody();
|
.expectBody(String.class).returnResult().getResponseBody();
|
||||||
assertThat(result).contains("Hello App").contains("Hello World");
|
assertThat(result).contains("Hello App").contains("Hello World");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPartialPage() throws Exception {
|
public void testPartialPage() throws Exception {
|
||||||
String result = (String) this.client.get().uri("/partial").exchange()
|
String result = this.client.get().uri("/partial").exchange().expectStatus().isOk()
|
||||||
.expectStatus().isOk()
|
|
||||||
.expectBody(String.class).returnResult().getResponseBody();
|
.expectBody(String.class).returnResult().getResponseBody();
|
||||||
assertThat(result).contains("Hello App").contains("Hello World");
|
assertThat(result).contains("Hello App").contains("Hello World");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@Import({ReactiveWebServerAutoConfiguration.class,
|
@Import({ ReactiveWebServerAutoConfiguration.class, WebFluxAutoConfiguration.class,
|
||||||
WebFluxAutoConfiguration.class,
|
|
||||||
HttpHandlerAutoConfiguration.class,
|
HttpHandlerAutoConfiguration.class,
|
||||||
PropertyPlaceholderAutoConfiguration.class})
|
PropertyPlaceholderAutoConfiguration.class })
|
||||||
@Controller
|
@Controller
|
||||||
public static class Application {
|
public static class Application {
|
||||||
|
|
||||||
|
|
@ -101,7 +97,8 @@ public class MustacheWebIntegrationTests {
|
||||||
@Bean
|
@Bean
|
||||||
public MustacheViewResolver viewResolver() {
|
public MustacheViewResolver viewResolver() {
|
||||||
Mustache.Compiler compiler = Mustache.compiler().withLoader(
|
Mustache.Compiler compiler = Mustache.compiler().withLoader(
|
||||||
new MustacheResourceTemplateLoader("classpath:/mustache-templates/", ".html"));
|
new MustacheResourceTemplateLoader("classpath:/mustache-templates/",
|
||||||
|
".html"));
|
||||||
MustacheViewResolver resolver = new MustacheViewResolver(compiler);
|
MustacheViewResolver resolver = new MustacheViewResolver(compiler);
|
||||||
resolver.setPrefix("classpath:/mustache-templates/");
|
resolver.setPrefix("classpath:/mustache-templates/");
|
||||||
resolver.setSuffix(".html");
|
resolver.setSuffix(".html");
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.mustache.servlet;
|
package org.springframework.boot.autoconfigure.mustache;
|
||||||
|
|
||||||
import java.lang.annotation.Documented;
|
import java.lang.annotation.Documented;
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
|
|
@ -34,14 +34,14 @@ import org.junit.runner.RunWith;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration;
|
|
||||||
import org.springframework.boot.autoconfigure.mustache.MustacheResourceTemplateLoader;
|
|
||||||
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration;
|
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||||
import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext;
|
import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext;
|
||||||
|
import org.springframework.boot.web.servlet.view.MustacheView;
|
||||||
|
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.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
@ -61,7 +61,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
|
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
|
||||||
public class MustacheWebIntegrationTests {
|
public class MustacheAutoConfigurationServletIntegrationTests {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ServletWebServerApplicationContext context;
|
private ServletWebServerApplicationContext context;
|
||||||
|
|
@ -79,8 +79,7 @@ public class MustacheWebIntegrationTests {
|
||||||
Template tmpl = Mustache.compiler().compile(source);
|
Template tmpl = Mustache.compiler().compile(source);
|
||||||
Map<String, String> context = new HashMap<>();
|
Map<String, String> context = new HashMap<>();
|
||||||
context.put("arg", "world");
|
context.put("arg", "world");
|
||||||
assertThat(tmpl.execute(context)).isEqualTo("Hello world!"); // returns "Hello
|
assertThat(tmpl.execute(context)).isEqualTo("Hello world!");
|
||||||
// world!"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -120,8 +119,8 @@ public class MustacheWebIntegrationTests {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public MustacheViewResolver viewResolver() {
|
public MustacheViewResolver viewResolver() {
|
||||||
Mustache.Compiler compiler = Mustache.compiler()
|
Mustache.Compiler compiler = Mustache.compiler().withLoader(
|
||||||
.withLoader(new MustacheResourceTemplateLoader("classpath:/mustache-templates/",
|
new MustacheResourceTemplateLoader("classpath:/mustache-templates/",
|
||||||
".html"));
|
".html"));
|
||||||
MustacheViewResolver resolver = new MustacheViewResolver(compiler);
|
MustacheViewResolver resolver = new MustacheViewResolver(compiler);
|
||||||
resolver.setPrefix("classpath:/mustache-templates/");
|
resolver.setPrefix("classpath:/mustache-templates/");
|
||||||
|
|
@ -19,9 +19,9 @@ package org.springframework.boot.autoconfigure.mustache;
|
||||||
import com.samskivert.mustache.Mustache;
|
import com.samskivert.mustache.Mustache;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.boot.autoconfigure.mustache.servlet.MustacheViewResolver;
|
|
||||||
import org.springframework.boot.test.util.EnvironmentTestUtils;
|
import org.springframework.boot.test.util.EnvironmentTestUtils;
|
||||||
import org.springframework.boot.web.reactive.context.GenericReactiveWebApplicationContext;
|
import org.springframework.boot.web.reactive.context.GenericReactiveWebApplicationContext;
|
||||||
|
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.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
@ -64,7 +64,7 @@ public class MustacheAutoConfigurationTests {
|
||||||
assertThat(this.reactiveWebContext.getBeansOfType(MustacheResourceTemplateLoader.class)).hasSize(1);
|
assertThat(this.reactiveWebContext.getBeansOfType(MustacheResourceTemplateLoader.class)).hasSize(1);
|
||||||
assertThat(this.reactiveWebContext.getBeansOfType(MustacheViewResolver.class)).isEmpty();
|
assertThat(this.reactiveWebContext.getBeansOfType(MustacheViewResolver.class)).isEmpty();
|
||||||
assertThat(this.reactiveWebContext
|
assertThat(this.reactiveWebContext
|
||||||
.getBeansOfType(org.springframework.boot.autoconfigure.mustache.reactive.MustacheViewResolver.class)
|
.getBeansOfType(org.springframework.boot.web.reactive.result.view.MustacheViewResolver.class)
|
||||||
).hasSize(1);
|
).hasSize(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -76,7 +76,7 @@ public class MustacheAutoConfigurationTests {
|
||||||
assertThat(this.reactiveWebContext.getBeansOfType(MustacheResourceTemplateLoader.class)).hasSize(1);
|
assertThat(this.reactiveWebContext.getBeansOfType(MustacheResourceTemplateLoader.class)).hasSize(1);
|
||||||
assertThat(this.reactiveWebContext.getBeansOfType(MustacheViewResolver.class)).isEmpty();
|
assertThat(this.reactiveWebContext.getBeansOfType(MustacheViewResolver.class)).isEmpty();
|
||||||
assertThat(this.reactiveWebContext
|
assertThat(this.reactiveWebContext
|
||||||
.getBeansOfType(org.springframework.boot.autoconfigure.mustache.reactive.MustacheViewResolver.class)
|
.getBeansOfType(org.springframework.boot.web.reactive.result.view.MustacheViewResolver.class)
|
||||||
).hasSize(1);
|
).hasSize(1);
|
||||||
assertThat(this.reactiveWebContext.getBean(Mustache.Compiler.class).standardsMode).isTrue();
|
assertThat(this.reactiveWebContext.getBean(Mustache.Compiler.class).standardsMode).isTrue();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,9 @@
|
||||||
<allow pkg="org.springframework.boot.web.servlet" />
|
<allow pkg="org.springframework.boot.web.servlet" />
|
||||||
<allow pkg="org.springframework.boot.web.server" />
|
<allow pkg="org.springframework.boot.web.server" />
|
||||||
</subpackage>
|
</subpackage>
|
||||||
|
<subpackage name="view">
|
||||||
|
<allow pkg="org.springframework.web.servlet" />
|
||||||
|
</subpackage>
|
||||||
</subpackage>
|
</subpackage>
|
||||||
|
|
||||||
<!-- Reactive -->
|
<!-- Reactive -->
|
||||||
|
|
@ -63,6 +66,11 @@
|
||||||
<allow pkg="org.springframework.boot.web.server" />
|
<allow pkg="org.springframework.boot.web.server" />
|
||||||
<disallow pkg="org.springframework.context" />
|
<disallow pkg="org.springframework.context" />
|
||||||
</subpackage>
|
</subpackage>
|
||||||
|
<subpackage name="result">
|
||||||
|
<subpackage name="view">
|
||||||
|
<allow pkg="org.springframework.boot.web.reactive.result.view" />
|
||||||
|
</subpackage>
|
||||||
|
</subpackage>
|
||||||
</subpackage>
|
</subpackage>
|
||||||
|
|
||||||
<!-- Embedded Servers -->
|
<!-- Embedded Servers -->
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,11 @@
|
||||||
<artifactId>jackson-databind</artifactId>
|
<artifactId>jackson-databind</artifactId>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.samskivert</groupId>
|
||||||
|
<artifactId>jmustache</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.sendgrid</groupId>
|
<groupId>com.sendgrid</groupId>
|
||||||
<artifactId>sendgrid-java</artifactId>
|
<artifactId>sendgrid-java</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.mustache.reactive;
|
package org.springframework.boot.web.reactive.result.view;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
|
@ -26,7 +26,7 @@ import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import com.samskivert.mustache.Mustache;
|
import com.samskivert.mustache.Mustache.Compiler;
|
||||||
import com.samskivert.mustache.Template;
|
import com.samskivert.mustache.Template;
|
||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
@ -46,18 +46,17 @@ import org.springframework.web.server.ServerWebExchange;
|
||||||
*/
|
*/
|
||||||
public class MustacheView extends AbstractUrlBasedView {
|
public class MustacheView extends AbstractUrlBasedView {
|
||||||
|
|
||||||
private Mustache.Compiler compiler;
|
private Compiler compiler;
|
||||||
|
|
||||||
private String charset;
|
private String charset;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the JMustache compiler to be used by this view.
|
* Set the JMustache compiler to be used by this view. Typically this property is not
|
||||||
* <p>Typically this property is not set directly. Instead a single
|
* set directly. Instead a single {@link Compiler} is expected in the Spring
|
||||||
* {@link Mustache.Compiler} is expected in the Spring application context
|
* application context which is used to compile Mustache templates.
|
||||||
* which is used to compile Mustache templates.
|
|
||||||
* @param compiler the Mustache compiler
|
* @param compiler the Mustache compiler
|
||||||
*/
|
*/
|
||||||
public void setCompiler(Mustache.Compiler compiler) {
|
public void setCompiler(Compiler compiler) {
|
||||||
this.compiler = compiler;
|
this.compiler = compiler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -74,27 +73,20 @@ public class MustacheView extends AbstractUrlBasedView {
|
||||||
return resolveResource() != null;
|
return resolveResource() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Resource resolveResource() {
|
|
||||||
Resource resource = getApplicationContext().getResource(getUrl());
|
|
||||||
if (resource == null || !resource.exists()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return resource;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Mono<Void> renderInternal(Map<String, Object> model,
|
protected Mono<Void> renderInternal(Map<String, Object> model, MediaType contentType,
|
||||||
MediaType contentType, ServerWebExchange exchange) {
|
ServerWebExchange exchange) {
|
||||||
Resource resource = resolveResource();
|
Resource resource = resolveResource();
|
||||||
if (resource == null) {
|
if (resource == null) {
|
||||||
return Mono.error(new IllegalStateException("Could not find Mustache template with URL ["
|
return Mono.error(new IllegalStateException(
|
||||||
+ getUrl() + "]"));
|
"Could not find Mustache template with URL [" + getUrl() + "]"));
|
||||||
}
|
}
|
||||||
DataBuffer dataBuffer = exchange.getResponse().bufferFactory().allocateBuffer();
|
DataBuffer dataBuffer = exchange.getResponse().bufferFactory().allocateBuffer();
|
||||||
try (Reader reader = getReader(resource)) {
|
try (Reader reader = getReader(resource)) {
|
||||||
Template template = this.compiler.compile(reader);
|
Template template = this.compiler.compile(reader);
|
||||||
Charset charset = getCharset(contentType).orElse(getDefaultCharset());
|
Charset charset = getCharset(contentType).orElse(getDefaultCharset());
|
||||||
try (Writer writer = new OutputStreamWriter(dataBuffer.asOutputStream(), charset)) {
|
try (Writer writer = new OutputStreamWriter(dataBuffer.asOutputStream(),
|
||||||
|
charset)) {
|
||||||
template.execute(model, writer);
|
template.execute(model, writer);
|
||||||
writer.flush();
|
writer.flush();
|
||||||
}
|
}
|
||||||
|
|
@ -105,6 +97,14 @@ public class MustacheView extends AbstractUrlBasedView {
|
||||||
return exchange.getResponse().writeWith(Flux.just(dataBuffer));
|
return exchange.getResponse().writeWith(Flux.just(dataBuffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Resource resolveResource() {
|
||||||
|
Resource resource = getApplicationContext().getResource(getUrl());
|
||||||
|
if (resource == null || !resource.exists()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
|
||||||
private Reader getReader(Resource resource) throws IOException {
|
private Reader getReader(Resource resource) throws IOException {
|
||||||
if (this.charset != null) {
|
if (this.charset != null) {
|
||||||
return new InputStreamReader(resource.getInputStream(), this.charset);
|
return new InputStreamReader(resource.getInputStream(), this.charset);
|
||||||
|
|
@ -113,6 +113,7 @@ public class MustacheView extends AbstractUrlBasedView {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<Charset> getCharset(MediaType mediaType) {
|
private Optional<Charset> getCharset(MediaType mediaType) {
|
||||||
return (mediaType != null ? Optional.ofNullable(mediaType.getCharset()) : Optional.empty());
|
return Optional.ofNullable(mediaType != null ? mediaType.getCharset() : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -14,9 +14,10 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.mustache.reactive;
|
package org.springframework.boot.web.reactive.result.view;
|
||||||
|
|
||||||
import com.samskivert.mustache.Mustache;
|
import com.samskivert.mustache.Mustache;
|
||||||
|
import com.samskivert.mustache.Mustache.Compiler;
|
||||||
|
|
||||||
import org.springframework.web.reactive.result.view.AbstractUrlBasedView;
|
import org.springframework.web.reactive.result.view.AbstractUrlBasedView;
|
||||||
import org.springframework.web.reactive.result.view.UrlBasedViewResolver;
|
import org.springframework.web.reactive.result.view.UrlBasedViewResolver;
|
||||||
|
|
@ -30,13 +31,13 @@ import org.springframework.web.reactive.result.view.ViewResolver;
|
||||||
*/
|
*/
|
||||||
public class MustacheViewResolver extends UrlBasedViewResolver {
|
public class MustacheViewResolver extends UrlBasedViewResolver {
|
||||||
|
|
||||||
private final Mustache.Compiler compiler;
|
private final Compiler compiler;
|
||||||
|
|
||||||
private String charset;
|
private String charset;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a {@code MustacheViewResolver} backed by a default
|
* Create a {@code MustacheViewResolver} backed by a default instance of a
|
||||||
* instance of a {@link Mustache.Compiler}.
|
* {@link Compiler}.
|
||||||
*/
|
*/
|
||||||
public MustacheViewResolver() {
|
public MustacheViewResolver() {
|
||||||
this.compiler = Mustache.compiler();
|
this.compiler = Mustache.compiler();
|
||||||
|
|
@ -44,11 +45,11 @@ public class MustacheViewResolver extends UrlBasedViewResolver {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a {@code MustacheViewResolver} backed by a custom
|
* Create a {@code MustacheViewResolver} backed by a custom instance of a
|
||||||
* instance of a {@link Mustache.Compiler}.
|
* {@link Compiler}.
|
||||||
* @param compiler the Mustache compiler used to compile templates
|
* @param compiler the Mustache compiler used to compile templates
|
||||||
*/
|
*/
|
||||||
public MustacheViewResolver(Mustache.Compiler compiler) {
|
public MustacheViewResolver(Compiler compiler) {
|
||||||
this.compiler = compiler;
|
this.compiler = compiler;
|
||||||
setViewClass(requiredViewClass());
|
setViewClass(requiredViewClass());
|
||||||
}
|
}
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Auto-configuration for Mustache with Spring WebFlux.
|
* Additional {@link org.springframework.web.reactive.result.view.View Views} for use with
|
||||||
|
* WebFlux.
|
||||||
*/
|
*/
|
||||||
package org.springframework.boot.autoconfigure.mustache.reactive;
|
package org.springframework.boot.web.reactive.result.view;
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.mustache.servlet;
|
package org.springframework.boot.web.servlet.view;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
|
@ -25,7 +25,7 @@ import java.util.Map;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import com.samskivert.mustache.Mustache;
|
import com.samskivert.mustache.Mustache.Compiler;
|
||||||
import com.samskivert.mustache.Template;
|
import com.samskivert.mustache.Template;
|
||||||
|
|
||||||
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.Resource;
|
||||||
|
|
@ -42,18 +42,19 @@ import org.springframework.web.servlet.view.AbstractTemplateView;
|
||||||
*/
|
*/
|
||||||
public class MustacheView extends AbstractTemplateView {
|
public class MustacheView extends AbstractTemplateView {
|
||||||
|
|
||||||
private Mustache.Compiler compiler;
|
private Compiler compiler;
|
||||||
|
|
||||||
private String charset;
|
private String charset;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the Mustache compiler to be used by this view.
|
* Set the Mustache compiler to be used by this view.
|
||||||
* <p>Typically this property is not set directly. Instead a single
|
* <p>
|
||||||
* {@link Mustache.Compiler} is expected in the Spring application context
|
* Typically this property is not set directly. Instead a single {@link Compiler} is
|
||||||
* which is used to compile Mustache templates.
|
* expected in the Spring application context which is used to compile Mustache
|
||||||
|
* templates.
|
||||||
* @param compiler the Mustache compiler
|
* @param compiler the Mustache compiler
|
||||||
*/
|
*/
|
||||||
public void setCompiler(Mustache.Compiler compiler) {
|
public void setCompiler(Compiler compiler) {
|
||||||
this.compiler = compiler;
|
this.compiler = compiler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -72,9 +73,10 @@ public class MustacheView extends AbstractTemplateView {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void renderMergedTemplateModel(Map<String, Object> model, HttpServletRequest request,
|
protected void renderMergedTemplateModel(Map<String, Object> model,
|
||||||
HttpServletResponse response) throws Exception {
|
HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||||
Template template = createTemplate(getApplicationContext().getResource(this.getUrl()));
|
Template template = createTemplate(
|
||||||
|
getApplicationContext().getResource(this.getUrl()));
|
||||||
if (template != null) {
|
if (template != null) {
|
||||||
template.execute(model, response.getWriter());
|
template.execute(model, response.getWriter());
|
||||||
}
|
}
|
||||||
|
|
@ -96,4 +98,5 @@ public class MustacheView extends AbstractTemplateView {
|
||||||
}
|
}
|
||||||
return new InputStreamReader(resource.getInputStream());
|
return new InputStreamReader(resource.getInputStream());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -14,9 +14,10 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.mustache.servlet;
|
package org.springframework.boot.web.servlet.view;
|
||||||
|
|
||||||
import com.samskivert.mustache.Mustache;
|
import com.samskivert.mustache.Mustache;
|
||||||
|
import com.samskivert.mustache.Mustache.Compiler;
|
||||||
|
|
||||||
import org.springframework.web.servlet.ViewResolver;
|
import org.springframework.web.servlet.ViewResolver;
|
||||||
import org.springframework.web.servlet.view.AbstractTemplateViewResolver;
|
import org.springframework.web.servlet.view.AbstractTemplateViewResolver;
|
||||||
|
|
@ -35,8 +36,8 @@ public class MustacheViewResolver extends AbstractTemplateViewResolver {
|
||||||
private String charset;
|
private String charset;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a {@code MustacheViewResolver} backed by a default
|
* Create a {@code MustacheViewResolver} backed by a default instance of a
|
||||||
* instance of a {@link Mustache.Compiler}.
|
* {@link Compiler}.
|
||||||
*/
|
*/
|
||||||
public MustacheViewResolver() {
|
public MustacheViewResolver() {
|
||||||
this.compiler = Mustache.compiler();
|
this.compiler = Mustache.compiler();
|
||||||
|
|
@ -44,11 +45,11 @@ public class MustacheViewResolver extends AbstractTemplateViewResolver {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a {@code MustacheViewResolver} backed by a custom
|
* Create a {@code MustacheViewResolver} backed by a custom instance of a
|
||||||
* instance of a {@link Mustache.Compiler}.
|
* {@link Compiler}.
|
||||||
* @param compiler the Mustache compiler used to compile templates
|
* @param compiler the Mustache compiler used to compile templates
|
||||||
*/
|
*/
|
||||||
public MustacheViewResolver(Mustache.Compiler compiler) {
|
public MustacheViewResolver(Compiler compiler) {
|
||||||
this.compiler = compiler;
|
this.compiler = compiler;
|
||||||
setViewClass(requiredViewClass());
|
setViewClass(requiredViewClass());
|
||||||
}
|
}
|
||||||
|
|
@ -15,6 +15,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Auto-configuration for Mustache with Spring MVC.
|
* Additional {@link org.springframework.web.servlet.View Views} for use with Web MVC.
|
||||||
*/
|
*/
|
||||||
package org.springframework.boot.autoconfigure.mustache.servlet;
|
package org.springframework.boot.web.servlet.view;
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.mustache.reactive;
|
package org.springframework.boot.web.reactive.result.view;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
@ -24,12 +24,15 @@ import org.springframework.context.support.GenericApplicationContext;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link org.springframework.boot.autoconfigure.mustache.reactive.MustacheViewResolver}.
|
* Tests for {@link MustacheViewResolver}.
|
||||||
*
|
*
|
||||||
* @author Brian Clozel
|
* @author Brian Clozel
|
||||||
*/
|
*/
|
||||||
public class MustacheViewResolverTests {
|
public class MustacheViewResolverTests {
|
||||||
|
|
||||||
|
private final String prefix = "classpath:/"
|
||||||
|
+ getClass().getPackage().getName().replace(".", "/") + "/";
|
||||||
|
|
||||||
private MustacheViewResolver resolver = new MustacheViewResolver();
|
private MustacheViewResolver resolver = new MustacheViewResolver();
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
|
|
@ -37,7 +40,7 @@ public class MustacheViewResolverTests {
|
||||||
GenericApplicationContext applicationContext = new GenericApplicationContext();
|
GenericApplicationContext applicationContext = new GenericApplicationContext();
|
||||||
applicationContext.refresh();
|
applicationContext.refresh();
|
||||||
this.resolver.setApplicationContext(applicationContext);
|
this.resolver.setApplicationContext(applicationContext);
|
||||||
this.resolver.setPrefix("classpath:/mustache-templates/");
|
this.resolver.setPrefix(this.prefix);
|
||||||
this.resolver.setSuffix(".html");
|
this.resolver.setSuffix(".html");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -48,7 +51,7 @@ public class MustacheViewResolverTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void resolveExisting() throws Exception {
|
public void resolveExisting() throws Exception {
|
||||||
assertThat(this.resolver.resolveViewName("foo", null).block()).isNotNull();
|
assertThat(this.resolver.resolveViewName("template", null).block()).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.mustache.reactive;
|
package org.springframework.boot.web.reactive.result.view;
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
@ -37,6 +37,9 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||||
*/
|
*/
|
||||||
public class MustacheViewTests {
|
public class MustacheViewTests {
|
||||||
|
|
||||||
|
private final String templateUrl = "classpath:/"
|
||||||
|
+ getClass().getPackage().getName().replace(".", "/") + "/template.html";
|
||||||
|
|
||||||
private GenericApplicationContext context = new GenericApplicationContext();
|
private GenericApplicationContext context = new GenericApplicationContext();
|
||||||
|
|
||||||
private MockServerWebExchange exchange;
|
private MockServerWebExchange exchange;
|
||||||
|
|
@ -51,11 +54,13 @@ public class MustacheViewTests {
|
||||||
this.exchange = MockServerHttpRequest.get("/test").toExchange();
|
this.exchange = MockServerHttpRequest.get("/test").toExchange();
|
||||||
MustacheView view = new MustacheView();
|
MustacheView view = new MustacheView();
|
||||||
view.setCompiler(Mustache.compiler());
|
view.setCompiler(Mustache.compiler());
|
||||||
view.setUrl("classpath:/mustache-templates/foo.html");
|
view.setUrl(this.templateUrl);
|
||||||
view.setCharset(StandardCharsets.UTF_8.displayName());
|
view.setCharset(StandardCharsets.UTF_8.displayName());
|
||||||
view.setApplicationContext(this.context);
|
view.setApplicationContext(this.context);
|
||||||
view.render(Collections.singletonMap("World", "Spring"), MediaType.TEXT_HTML, this.exchange).block();
|
view.render(Collections.singletonMap("World", "Spring"), MediaType.TEXT_HTML,
|
||||||
assertThat(this.exchange.getResponse().getBodyAsString().block()).isEqualTo("Hello Spring");
|
this.exchange).block();
|
||||||
|
assertThat(this.exchange.getResponse().getBodyAsString().block())
|
||||||
|
.isEqualTo("Hello Spring");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.mustache.servlet;
|
package org.springframework.boot.web.servlet.view;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
@ -33,6 +33,9 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||||
*/
|
*/
|
||||||
public class MustacheViewResolverTests {
|
public class MustacheViewResolverTests {
|
||||||
|
|
||||||
|
private final String prefix = "classpath:/"
|
||||||
|
+ getClass().getPackage().getName().replace(".", "/") + "/";
|
||||||
|
|
||||||
private MustacheViewResolver resolver = new MustacheViewResolver();
|
private MustacheViewResolver resolver = new MustacheViewResolver();
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
|
|
@ -41,7 +44,7 @@ public class MustacheViewResolverTests {
|
||||||
applicationContext.refresh();
|
applicationContext.refresh();
|
||||||
this.resolver.setApplicationContext(applicationContext);
|
this.resolver.setApplicationContext(applicationContext);
|
||||||
this.resolver.setServletContext(new MockServletContext());
|
this.resolver.setServletContext(new MockServletContext());
|
||||||
this.resolver.setPrefix("classpath:/mustache-templates/");
|
this.resolver.setPrefix(this.prefix);
|
||||||
this.resolver.setSuffix(".html");
|
this.resolver.setSuffix(".html");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -52,13 +55,13 @@ public class MustacheViewResolverTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void resolveExisting() throws Exception {
|
public void resolveExisting() throws Exception {
|
||||||
assertThat(this.resolver.resolveViewName("foo", null)).isNotNull();
|
assertThat(this.resolver.resolveViewName("template", null)).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void setsContentType() throws Exception {
|
public void setsContentType() throws Exception {
|
||||||
this.resolver.setContentType("application/octet-stream");
|
this.resolver.setContentType("application/octet-stream");
|
||||||
View view = this.resolver.resolveViewName("foo", null);
|
View view = this.resolver.resolveViewName("template", null);
|
||||||
assertThat(view.getContentType()).isEqualTo("application/octet-stream");
|
assertThat(view.getContentType()).isEqualTo("application/octet-stream");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.mustache.servlet;
|
package org.springframework.boot.web.servlet.view;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
|
|
@ -37,6 +37,9 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||||
*/
|
*/
|
||||||
public class MustacheViewTests {
|
public class MustacheViewTests {
|
||||||
|
|
||||||
|
private final String templateUrl = "classpath:/"
|
||||||
|
+ getClass().getPackage().getName().replace(".", "/") + "/template.html";
|
||||||
|
|
||||||
private MockHttpServletRequest request = new MockHttpServletRequest();
|
private MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
|
|
||||||
private MockHttpServletResponse response = new MockHttpServletResponse();
|
private MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
|
|
@ -57,9 +60,10 @@ public class MustacheViewTests {
|
||||||
public void viewResolvesHandlebars() throws Exception {
|
public void viewResolvesHandlebars() throws Exception {
|
||||||
MustacheView view = new MustacheView();
|
MustacheView view = new MustacheView();
|
||||||
view.setCompiler(Mustache.compiler());
|
view.setCompiler(Mustache.compiler());
|
||||||
view.setUrl("classpath:/mustache-templates/foo.html");
|
view.setUrl(this.templateUrl);
|
||||||
view.setApplicationContext(this.context);
|
view.setApplicationContext(this.context);
|
||||||
view.render(Collections.singletonMap("World", "Spring"), this.request, this.response);
|
view.render(Collections.singletonMap("World", "Spring"), this.request,
|
||||||
|
this.response);
|
||||||
assertThat(this.response.getContentAsString()).isEqualTo("Hello Spring");
|
assertThat(this.response.getContentAsString()).isEqualTo("Hello Spring");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Hello {{World}}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Hello {{World}}
|
||||||
Loading…
Reference in New Issue