Commit 304920df authored by Dave Syer's avatar Dave Syer Committed by Phillip Webb

Make Thymeleaf @ConditionalOnWebApplication

If user creates a Thymeleaf app with a parent-child context then the
child should contain all the web-specific pieces (and they are likely
to fail fast if they need to be ServletContextAware, or slower if they
try to locate a WebApplicationContext at runtime). This can't happen
if the view resolver is being added to the parent.

Freemarker and Velocity already have similar tests because it is assumed
that they should be usable outside a web app, so this change just does the
same for Thymeleaf.

Fixes gh-1611
parent 68ff7d45
...@@ -29,6 +29,7 @@ import org.springframework.boot.autoconfigure.AutoConfigureAfter; ...@@ -29,6 +29,7 @@ import org.springframework.boot.autoconfigure.AutoConfigureAfter;
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.web.WebMvcAutoConfiguration; import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
import org.springframework.boot.bind.RelaxedPropertyResolver; import org.springframework.boot.bind.RelaxedPropertyResolver;
import org.springframework.context.EnvironmentAware; import org.springframework.context.EnvironmentAware;
...@@ -149,19 +150,20 @@ public class ThymeleafAutoConfiguration { ...@@ -149,19 +150,20 @@ public class ThymeleafAutoConfiguration {
@Configuration @Configuration
@ConditionalOnClass({ Servlet.class }) @ConditionalOnClass({ Servlet.class })
@ConditionalOnWebApplication
protected static class ThymeleafViewResolverConfiguration implements EnvironmentAware { protected static class ThymeleafViewResolverConfiguration implements EnvironmentAware {
private RelaxedPropertyResolver environment; private RelaxedPropertyResolver environment;
@Autowired
private SpringTemplateEngine templateEngine;
@Override @Override
public void setEnvironment(Environment environment) { public void setEnvironment(Environment environment) {
this.environment = new RelaxedPropertyResolver(environment, this.environment = new RelaxedPropertyResolver(environment,
"spring.thymeleaf."); "spring.thymeleaf.");
} }
@Autowired
private SpringTemplateEngine templateEngine;
@Bean @Bean
@ConditionalOnMissingBean(name = "thymeleafViewResolver") @ConditionalOnMissingBean(name = "thymeleafViewResolver")
public ThymeleafViewResolver thymeleafViewResolver() { public ThymeleafViewResolver thymeleafViewResolver() {
......
...@@ -30,6 +30,7 @@ import org.springframework.mock.web.MockHttpServletRequest; ...@@ -30,6 +30,7 @@ import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletContext; import org.springframework.mock.web.MockServletContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.support.RequestContext; import org.springframework.web.servlet.support.RequestContext;
import org.thymeleaf.TemplateEngine; import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context; import org.thymeleaf.context.Context;
...@@ -38,8 +39,10 @@ import org.thymeleaf.spring4.view.ThymeleafViewResolver; ...@@ -38,8 +39,10 @@ import org.thymeleaf.spring4.view.ThymeleafViewResolver;
import org.thymeleaf.templateresolver.ITemplateResolver; import org.thymeleaf.templateresolver.ITemplateResolver;
import org.thymeleaf.templateresolver.TemplateResolver; import org.thymeleaf.templateresolver.TemplateResolver;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
/** /**
...@@ -49,7 +52,7 @@ import static org.junit.Assert.assertTrue; ...@@ -49,7 +52,7 @@ import static org.junit.Assert.assertTrue;
*/ */
public class ThymeleafAutoConfigurationTests { public class ThymeleafAutoConfigurationTests {
private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); private AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
@After @After
public void close() { public void close() {
...@@ -137,4 +140,44 @@ public class ThymeleafAutoConfigurationTests { ...@@ -137,4 +140,44 @@ public class ThymeleafAutoConfigurationTests {
context.close(); context.close();
} }
@Test
public void useDataDialect() throws Exception {
this.context.register(ThymeleafAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
this.context.refresh();
TemplateEngine engine = this.context.getBean(TemplateEngine.class);
Context attrs = new Context(Locale.UK, Collections.singletonMap("foo", "bar"));
String result = engine.process("data-dialect", attrs);
assertEquals("<html><body data-foo=\"bar\"></body></html>", result);
}
@Test
public void renderTemplate() throws Exception {
this.context.register(ThymeleafAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
this.context.refresh();
TemplateEngine engine = this.context.getBean(TemplateEngine.class);
Context attrs = new Context(Locale.UK, Collections.singletonMap("foo", "bar"));
String result = engine.process("home", attrs);
assertEquals("<html><body>bar</body></html>", result);
}
@Test
public void renderNonWebAppTemplate() throws Exception {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
ThymeleafAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
assertEquals(0, context.getBeanNamesForType(ViewResolver.class).length);
try {
TemplateEngine engine = context.getBean(TemplateEngine.class);
Context attrs = new Context(Locale.UK, Collections.singletonMap("greeting",
"Hello World"));
String result = engine.process("message", attrs);
assertThat(result, containsString("Hello World"));
}
finally {
context.close();
}
}
} }
...@@ -81,7 +81,8 @@ public class BasicErrorControllerIntegrationTest { ...@@ -81,7 +81,8 @@ public class BasicErrorControllerIntegrationTest {
"http://localhost:" + this.port + "/bind", Map.class); "http://localhost:" + this.port + "/bind", Map.class);
String resp = entity.getBody().toString(); String resp = entity.getBody().toString();
assertThat(resp, containsString("Error count: 1")); assertThat(resp, containsString("Error count: 1"));
assertThat(resp, containsString("errors=[{codes=")); assertThat(resp, containsString("errors=[{"));
assertThat(resp, containsString("codes=["));
assertThat(resp, containsString("org.springframework.validation.BindException")); assertThat(resp, containsString("org.springframework.validation.BindException"));
} }
......
<html><body th:text="${foo}">Home</body></html>
\ No newline at end of file
<html><body>Message: <span th:text="${greeting}">Hello</span></body></html>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment