【问题标题】:Apache Velocity 2.0 how to write a custom resource loader?Apache Velocity 2.0 如何编写自定义资源加载器?
【发布时间】:2019-11-29 07:47:43
【问题描述】:

API 文档中有一个ResourceLoader 类:

https://velocity.apache.org/engine/2.0/apidocs/org/apache/velocity/runtime/resource/loader/ResourceLoader.html

我想实现我自己的加载器,因为我需要从数据库加载模板,但是以上下文敏感的方式(换句话说:DataSourceResourceLoader不能使用,我需要编写自定义代码来选择“正确”数据库中的模板)。

ResourceLoader似乎有一些抽象方法,而且我似乎也可以通过实现这些抽象方法来编写自定义加载器。但是我看不到任何方法可以向引擎添加新的加载程序。没有“addResourceLoader”方法。该文档仅显示了如何配置 Velocity 内置的加载器:

https://velocity.apache.org/engine/2.0/developer-guide.html#resource-loaders

主要问题:如何将自定义资源加载器添加到 VelocityEngine(或 VelocityContext?)

另一个问题:我想关闭所有内置加载程序。尤其是WebappResourceLoader,它默认处于活动状态,在我的特定应用程序中代表着安全风险。该怎么做?

【问题讨论】:

    标签: java velocity


    【解决方案1】:

    我无法回答如何实现自己的资源加载器,但第二部分很简单:

    当您创建 VelocityEngine 时,您可以传递定义资源加载器“类路径”的属性

    不同的类加载器由属性键的前缀标识。就像这样:

    Properties props = new Properties();
    
    // Add a default class path resource loader - just an example
    props.setProperty("cp.resource.loader.class", ClasspathResourceLoader.class.getName());
    props.setProperty("cp.resource.loader.cache", "true);
    
    // Add your own resource loader
    props.setProperty("db.resource.loader.class", MyDBResourceLoader.class.getName());
    props.setProperty("db.resource.loader.cache", "false");
    
    // Define the "class path" for the loaders
    // in this case first the "db" loader is asked for resources, if nothing is found the "cp" loader
    props.setProperty(RuntimeConstants.RESOURCE_LOADER, "db,cp");
    
    // Now create the engine
    VelocityEngine engine = new VelocityEngine(props);
    

    上面只为该引擎定义了两个资源加载器,该引擎实例不会使用其他加载器。

    【讨论】:

      【解决方案2】:

      您必须首先实现ResourceLoader 接口(或子类化现有资源加载器),然后在velocity.properties 中声明您的资源加载器:

      resource.loader = .... , my_loader, ...
      my_loader.resource.loader.class = com.foo.MyResourceLoader
      my_loader.resource.loader.some_property = some_value
      ... other properties...
      

      请注意,配置属性语法在 2.1 版中有所改变。虽然旧语法仍然有效,但如果您想避免在日志中出现弃用警告,那就是:

      resource.loaders = .... , my_loader, ...
      resource.loader.my_loader.class = com.foo.MyResourceLoader
      resource.loader.m_loader.some_property = some_value
      ... other properties...
      

      has ResourceLoader 接口有四个你需要提供的抽象方法:

      • void init(ExtProperties configuration) 其中configuration 对象包含some_property -> some_value 属性对
      • long getLastModified(Resource resource) 返回资源被修改后的秒数
      • Reader getResourceReader(String source, String encoding)获取资源的实际内容
      • boolean isSourceModified(Resource resource)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-14
        • 1970-01-01
        • 2016-07-23
        • 2012-11-20
        • 1970-01-01
        相关资源
        最近更新 更多