The solution we finished consisted of a new IResourceResolver with a custom Context , not a custom TemplateResolver . We chose this because in most cases we still wanted to use class scanning, but sometimes had dynamic content.
The following shows how we did this:
public class StringAndClassLoaderResourceResolver implements IResourceResolver { public StringAndClassLoaderResourceResolver() { super(); } public String getName() { return getClass().getName().toUpperCase(); } public InputStream getResourceAsStream(final TemplateProcessingParameters params, final String resourceName) { Validate.notNull(resourceName, "Resource name cannot be null"); if( StringContext.class.isAssignableFrom( params.getContext().getClass() ) ){ String content = ((StringContext)params.getContext()).getContent(); return IOUtils.toInputStream(content); } return ClassLoaderUtils.getClassLoader(ClassLoaderResourceResolver.class).getResourceAsStream(resourceName); } public static class StringContext extends Context{ private final String content; public StringContext(String content) { this.content = content; } public StringContext(String content, Locale locale) { super(locale); this.content = content; } public StringContext(String content, Locale locale, Map<String, ?> variables) { super(locale, variables); this.content = content; } public String getContent() { return content; } }
Test case
public class StringAndClassLoaderResourceResolverTest { private static SpringTemplateEngine templateEngine; @BeforeClass public static void setup(){ TemplateResolver resolver = new TemplateResolver(); resolver.setResourceResolver(new StringAndClassLoaderResourceResolver()); resolver.setPrefix("mail/"); // src/test/resources/mail resolver.setSuffix(".html"); resolver.setTemplateMode("LEGACYHTML5"); resolver.setCharacterEncoding(CharEncoding.UTF_8); resolver.setOrder(1); templateEngine = new SpringTemplateEngine(); templateEngine.setTemplateResolver(resolver); } @Test public void testStringResolution() { String expected = "<div>dave</div>"; String input = "<div th:text=\"${userName}\">Some Username Here!</div>"; IContext context = new StringAndClassLoaderResourceResolver.StringContext(input); context.getVariables().put("userName", "dave"); String actual = templateEngine.process("redundant", context); assertEquals(expected, actual); } @Test public void testClasspathResolution(){ IContext context = new Context(); context.getVariables().put("message", "Hello Thymeleaf!"); String actual = templateEngine.process("dummy", context); String expected = "<h1>Hello Thymeleaf!</h1>"; assertEquals(expected, actual); } }
Dummy file template file in src / main / resources / mail / dummy.html
<h1 th:text="${message}">A message will go here!</h1>
Note. We used Apache CommonsIO IOUtils to convert String to InputStream
David welch
source share