Is there a way to make Spring Thymeleaf process a string template?

后端 未结 4 1599
-上瘾入骨i
-上瘾入骨i 2020-12-14 11:00

I would like to write something like :

    @Autowired
    private SpringTemplateEngine engine;
....
  // Thymeleaf Context
  WebContext thymeleafContext = ne         


        
相关标签:
4条回答
  • 2020-12-14 11:08

    for simple unit tests:

    static class TestResourceResolver implements IResourceResolver {
        public String content = "";
    
        @Override
        public String getName() {
            return "TestTemplateResolver";
        }
    
        @Override
        public InputStream getResourceAsStream(TemplateProcessingParameters templateProcessingParameters,
                String resourceName) {
            return new ByteArrayInputStream(content.getBytes());
        }
    }
    

    or just use org.thymeleaf.templateresolver.StringTemplateResolver in Thymeleaf 3

    0 讨论(0)
  • 2020-12-14 11:20

    You can implement your own TemplateResolver and IResourceResolver to work with String.

    0 讨论(0)
  • 2020-12-14 11:29

    The solution we ended up using consisted of a new IResourceResolver with a custom Context rather than a custom TemplateResolver. We chose this because we still wanted to use classpath scanning in most cases, but occasionally had dynamic content.

    The following shows how we did it:

    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 template file at src/main/resources/mail/dummy.html

    <h1 th:text="${message}">A message will go here!</h1>
    

    Note: We used Apache CommonsIO's IOUtils for converting the String to an InputStream

    0 讨论(0)
  • 2020-12-14 11:29

    Yep StringTemplateResolver is the way to go.

    public class ReportTemplateEngine {
    
        private static TemplateEngine instance;
    
        private ReportTemplateEngine() {}
    
        public static TemplateEngine getInstance() {
            if(instance == null){
                synchronized (ReportTemplateEngine.class) {
                    if(instance == null) {
                        instance = new TemplateEngine();
                        StringTemplateResolver templateResolver = new StringTemplateResolver();
                        templateResolver.setTemplateMode(TemplateMode.HTML);
                        instance.setTemplateResolver(templateResolver);
                    }
                }
            }
            return instance;
        }
    }
    
    0 讨论(0)
提交回复
热议问题