java - Apache Velocity 禁用模板和资源缓存

标签 java spring-mvc velocity

我有一个 Spring Boot 应用程序,它公开了一个用于渲染相对简单的速度模板的 API。该模板使用#parse 来包含其他几个模板,并以其他方式写出从 Java 层传递给它的一些基本变量。模板位于 JAR 文件内,因此它们是从类路径加载的。我使用以下根据请求即时创建的速度引擎设置:

    VelocityEngine ve = new VelocityEngine();
    ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
    ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
    ve.setProperty("classpath.resource.loader.cache", "false");
    ve.setProperty("velocity.engine.resource.manager.cache.enabled", "false");
    ve.setProperty("resource.manager.cache.enabled", "false");
    ve.init();

模板的多个部分对于每个请求都是唯一的(资源用作对简单 Spring MVC Controller 的响应),因此我需要禁用模板资源的缓存。我已按原样尝试了上述配置,并在 src/main/resources 中的 velocity.properties 文件中定义它,但更改了模板或文件直到我重新启动应用程序后才“生效”。

做什么this documentation页面说似乎没有帮助(实际上你可以看到上面它的作用)。

上面的引擎代码位于 Spring Component 类中,即使将 VelocityEngine 内容移动到静态最终字段并且每次都初始化速度上下文也无济于事。

如何强制 Spring/Velocity 每次加载模板和包含的资源?

最佳答案

您只需要classpath.resource.loader.cache配置键。由于 Velocity 中的所有缓存都默认为 false,因此您甚至不需要它。

此外,无需在每次请求时重新初始化 VelocityEngine。

我使用以下小测试程序检查了修改后资源是否正确重新加载:

import java.io.PrintWriter;
import java.io.Writer;
import java.util.Scanner;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;    

public class Test
{
    public static void main(String args[])
    {
        try
        {
            VelocityEngine ve = new VelocityEngine();
            ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
            ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
            // next line not needed since 'false' is the default
            // ve.setProperty("classpath.resource.loader.cache", "false");
            ve.init();

            VelocityContext context = new VelocityContext();
            Writer writer = new PrintWriter(System.out);
            Scanner scan = new Scanner(System.in);
            while (true)
            {
                System.out.print("> ");
                String str = scan.next();
                context.put("foo", str);
                ve.mergeTemplate("test.vm", "UTF-8", context, writer);
                writer.flush();
            }
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
}

如果它在您的情况下不起作用,并且尤其如果您在每个请求时重新初始化 Velocity,那么这肯定是 Spring 本身的 ClassLoader 缓存问题。

所以你应该检查 Spring Hot Swapping guide查看如何禁用缓存。我想对 Spring 有更深入了解的人可以给您一些关于如何在这种特殊情况下继续进行的提示。

关于java - Apache Velocity 禁用模板和资源缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37953420/

相关文章:

Java 泛型 : Generic parameter defined at method level vs interface level

java - 基于变量加载另一个 spring beans 文件?

java - 使用 Retrofit 读取 JSON

java - Hadoop:从 JAVA 测量洗牌时间

java - 我不知所措地从 Spring XML 迁移到 Java-config

java - 当请求 Content-Type 为 gzip 时,Jetty 响应 400 Bad Request

java - Hibernate 在本地机器上工作但在 Heroku 上失败

java - 我可以改进 XWiki 搜索结果以包含关键字匹配吗?

java - 为什么在 Spring 4.3 中不推荐使用 Velocity 支持?

java - 在 Velocity 文件中将日期格式化为葡萄牙语