如何将速度模板加载到EJB中以用作邮件模板

时间:2010-11-13 23:33:08

标签: java templates jsf classloader velocity

我有一个Java EE 6应用程序,我想在其中使用velocity从模板生成邮件。我有一个@Named bean,负责加载和填充特定模板。该项目是一个Web应用程序,所以我将我的模板放入WEB-INF / classes(这看起来相当丑陋,但我现在没有找到更优雅的解决方案)并使用ClasspathResourceLoader来访问文件。配置如下:

Properties props = new Properties();
props.setProperty("resource.loader", "class");
props.setProperty("resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");

VelocityEngine engine = new VelocityEngine(props);
VelocityContext context = new VelocityContext();

engine.init();

context.put("myObject", myObject);
Template template = engine.getTemplate("mail_template.vm");

StringWriter writer = new StringWriter();
template.merge(context, writer);

运行此代码会产生以下异常:

Caused by: java.lang.UnsupportedOperationException: Could not retrieve ServletContext from application attributes
    at org.apache.velocity.runtime.log.ServletLogChute.init(ServletLogChute.java:73)
    at org.apache.velocity.runtime.log.LogManager.createLogChute(LogManager.java:157)

所以我需要将ServletContext交给速度引擎。但我的bean不知道上下文,我不想使用servlet发送邮件。 frontent是用JSF 2.0实现的,所以我可以访问FacesContext.getCurrentInstance()。getExternalContext()。getContext(),将它转换为ServletContext并将其提供给引擎。然而,上下文总是为空,我不知道如何使一切工作。每个提示/解决方案都受到高度赞赏:)

提前致谢, 亚历

1 个答案:

答案 0 :(得分:2)

Velocity可以在任何环境中运行,因此不需要servlet。似乎该问题与日志记录工具有关,其缺省值取决于servlet。

您可以使用NullLogChute,或者根据您的日志记录框架,选择实现LogChute的类。例如,如果您使用commons-logging,则需要CommonsLogLogChute。如何设置:

  

要使用,首先设置commons-logging,然后通过在velocity.properties中添加以下内容告诉Velocity使用此类进行日志记录:runtime.log.logsystem.class = org.apache.velocity.runtime.log。 CommonsLogLogChute

     

您也可以设置此属性以指定应记录Velocity的消息的日志/名称(以下示例为默认值)。 runtime.log.logsystem.commons.logging.name = org.apache.velocity

因此,除了在velocity.properties中提供此设置外,您还可以调用:

engine.setProperty("runtime.log.logsystem.class", 
       "org.apache.velocity.runtime.log.CommonsLogLogChute");