Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring mvc 有没有一种方法可以使SpringTelieAF进程成为字符串模板?_Spring Mvc_Thymeleaf - Fatal编程技术网

Spring mvc 有没有一种方法可以使SpringTelieAF进程成为字符串模板?

Spring mvc 有没有一种方法可以使SpringTelieAF进程成为字符串模板?,spring-mvc,thymeleaf,Spring Mvc,Thymeleaf,我想写一些类似于: @Autowired private SpringTemplateEngine engine; .... // Thymeleaf Context WebContext thymeleafContext = new WebContext(request, response, request.getServletContext(), locale); // cached html of a thymeleaf template file

我想写一些类似于:

    @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]方法不能这样做。我可以从文档中了解到,我需要一个特殊的模板解析器:

为了执行模板,将使用process(String,IContext)方法: 最终字符串结果=templateEngine.process(“mytemplate”,ctx); “mytemplate”字符串参数是模板名称,它将以模板解析程序配置的方式与模板本身的物理/逻辑位置相关

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


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

您可以实现自己的
TemplateResolver
IResourceResolver
来处理
字符串

我们最终使用的解决方案由一个新的
IResourceResolver
和一个自定义的
上下文组成
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;
        }
    }
公共类StringAndClassLoaderResourceResolver实现IResourceResolver{
public StringAndClassLoaderResourceSolver(){
超级();
}
公共字符串getName(){
返回getClass().getName().toUpperCase();
}
public InputStream getResourceAsStream(最终模板处理参数参数,最终字符串resourceName){
Validate.notNull(resourceName,“资源名称不能为null”);
if(StringContext.class.isAssignableFrom(params.getContext().getClass())){
字符串内容=((StringContext)params.getContext()).getContent();
返回IOUtils.toInputStream(内容);
}
返回ClassLoaderUtils.getClassLoader(classLoaderResourceSolver.class).getResourceAsStream(resourceName);
}
公共静态类StringContext扩展了上下文{
私有最终字符串内容;
公共字符串上下文(字符串内容){
this.content=内容;
}
公共StringContext(字符串内容、区域设置){
超级(现场);
this.content=内容;
}
公共StringContext(字符串内容、区域设置、映射变量){
super(语言环境、变量);
this.content=内容;
}
公共字符串getContent(){
返回内容;
}
}
测试用例

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);
    }
}
公共类StringAndClassLoaderResourceResolverTest{
私有静态SpringTemplateEngine模板引擎;
@课前
公共静态无效设置(){
TemplateResolver解析器=新TemplateResolver();
setResourceResolver(新StringAndClassLoaderResourceResolver());
resolver.setPrefix(“mail/”;//src/test/resources/mail
resolver.setSuffix(“.html”);
resolver.setTemplateMode(“LEGACYHTML5”);
解析器.setCharacterEncoding(CharEncoding.UTF_8);
解析程序设置顺序(1);
templateEngine=新的SpringTemplateEngine();
templateEngine.setTemplateResolver(分解器);
}
@试验
公开无效的testStringResolution(){
字符串应为=“dave”;
String input=“此处有用户名!”;
IContext context=new StringAndClassLoaderResourceSolver.StringContext(输入);
context.getVariables().put(“用户名”、“dave”);
字符串实际值=templateEngine.process(“冗余”,上下文);
资产质量(预期、实际);
}
@试验
public void testClasspathResolution(){
IContext context=新上下文();
context.getVariables().put(“message”,“Hello Thymeleaf!”);
String actual=templateEngine.process(“dummy”,上下文);
字符串应为=“Hello Thymeleaf!”;
资产质量(预期、实际);
}
}
src/main/resources/mail/Dummy.html上的虚拟模板文件

<h1 th:text="${message}">A message will go here!</h1>
将在此处发送消息!
注意:我们使用ApacheCommonsio的IOUtils将字符串转换为InputStream,用于简单的单元测试:

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

或者只需在thymeleaf 3中使用
org.thymeleaf.templateresolver.StringTemplateResolver
是的,StringTemplateResolver是一个不错的选择

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

为什么?Thymeleaf默认情况下已经缓存解析过的模板。很好。我不知道。缓存的到底是什么?处理前的裸模板还是处理后的模板?对我来说不一样。我想缓存裸模板。很好!我当然会使用你的解决方案。呃,Singleton…他使用Spring定义了
StringTemplateResolver
Bean,默认情况下是单例的,会更好。