How to load a velocity template into an EJB to be used as a mail template

自作多情 提交于 2019-12-10 10:27:43

问题


I have a Java EE 6 application in which I'd like to use velocity to generate mails from a template. I have a @Named bean which is responsible for loading and filling a particular template. The project is a web application, so I placed my templates into WEB-INF/classes (which btw seems to be rather ugly, but I didn't find a more elegant solution by now) and used the ClasspathResourceLoader to access the files. The configuration is as follows:

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

Running this code produces the follwing exception:

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)

So I'm required to hand in the ServletContext to the velocity engine. But my bean is not aware of that context and I don't want to use a servlet for sending mails. The frontent is implemented with JSF 2.0 so I can access FacesContext.getCurrentInstance().getExternalContext().getContext(), cast it to ServletContext and provide it to the engine. However the context is always null, and I just have no clue how to get everything up working. Every hint / solution is highly appreciated :)

Thanks in advance, Alex


回答1:


Velocity can run in any environment, so servlets are not a requirement. It seems that the problem is related to the logging facility, whose default depends on a servlet.

You can use a NullLogChute, or, depending on your logging framework, choose a class implementing LogChute. So for example, if you use commons-logging, you'd need CommonsLogLogChute. How to set it up:

To use, first set up commons-logging, then tell Velocity to use this class for logging by adding the following to your velocity.properties: runtime.log.logsystem.class = org.apache.velocity.runtime.log.CommonsLogLogChute

You may also set this property to specify what log/name Velocity's messages should be logged to (example below is default). runtime.log.logsystem.commons.logging.name = org.apache.velocity

So, apart from providing this setting in velocity.properties, you can call:

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


来源:https://stackoverflow.com/questions/4175302/how-to-load-a-velocity-template-into-an-ejb-to-be-used-as-a-mail-template

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!