当前位置: 首页 > 知识库问答 >
问题:

有没有办法使Spring Thymeleaf进程成为字符串模板?

柯轶
2023-03-14

我想写这样的东西:

    @Autowired
    private SpringTemplateEngine engine;
....
  // Thymeleaf Context
  WebContext thymeleafContext = new WebContext(request, response, request.getServletContext(), locale);

    // cached html of a thymeleaf template file
    String cachedHtml=....

    // process the cached html
  String html=engine.process(cachedHtml, thymeleafContext);

默认情况下,[process]方法不能这样做。我可以从文档中了解到,我需要一个特殊的模板解析器:

为了执行模板,将使用过程(String,IContext)方法:最终String结果=templateEngine.process("my模板",ctx);"my模板"String参数是模板名称,它将与模板的物理/逻辑位置相关以在模板解析器处配置自身的方式/s。

有人知道如何解决我的问题吗?

目标是缓存字符串中的Thymeleaf模板(文件),然后处理这些字符串而不是文件。

共有3个答案

薄哲
2023-03-14

对于简单的单元测试:

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());
    }
}

或者直接使用org。百里香。templateresolver。Thymeleaf 3中的StringTemplateResolver

鞠通
2023-03-14

您可以实现自己的TemplateResolverIResourceResolver来使用String

范峰
2023-03-14

我们最终使用的解决方案包括一个新的IResourceResolver,它具有自定义的Context,而不是自定义的TemplateResolver。我们选择这个是因为我们仍然希望在大多数情况下使用类路径扫描,但偶尔会有动态内容。

下面展示了我们是如何做到这一点的:

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;
        }
    }

测试用例

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);
    }
}

src/main/Resources/mail/dummy.html的假模板文件

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

注意:我们使用ApacheCommonsio的IOUtils将字符串转换为InputStream

 类似资料:
  • 我想知道是否有一种方法可以基于字符串生成相同的UUID 我尝试使用UUID,它似乎没有提供此功能。

  • 问题内容: 我希望使用番石榴将其连接成一个字符串,但列表中的每个字符串周围都有环绕的字符串。所以我想列出一个字符串列表: 并生成此字符串: 我看到的示例似乎是生成3个以逗号分隔的名称,但我希望每个字符串都包含一些额外的字符串(每次都相同)。 我希望我在这里足够清楚。谢谢你的帮助。 问题答案: 为此,首先要进行转换:

  • 我正试图在表格上做错误检查。我想看看一个电话号码是否有效,看它是否包含所有号码。有没有办法确定一个字符串中是否只有NMBER?

  • 我正在生成AES-256密钥使用: 有没有办法将字节数组看作字符串?对我有效的唯一方法是: 如果我打印并复制字符串,并尝试使用在线Base64解码器对其进行解码,它会抱怨字符串不是UTF-8。 我知道它违背了加密的目的,但有没有办法可以将静态32个字符长的字符串分配为密钥?

  • 编程新手,如果这是个愚蠢的问题,我深表歉意。 当使用Scanner类时,我看不出是否有获取单个字符作为输入的选项。例如 上面的代码允许我将下一行拉入字符串,然后可以使用while或if语句使用.length()对其进行验证1,然后根据需要存储到字符中。 但是,有没有一种方法可以提取单个字符,而不是使用字符串然后进行验证?如果没有,有人能解释为什么这是不允许的吗?我认为这可能是由于类或对象与基本类型

  • 假设我生成了一个具有多个属性的域对象。我想为defn类中的一个对象属性生成@jsonignore注释。