可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Something is wrong and it is very frustrating. I read on velocity's homepage that when I run a webapp then some properties should be set. And I've done that but no matter what I do I keep getting the same error.
This is where I set the props and use velocity
public class ConfirmationMailGenerator implements MailGenerator { private BasicUser user; private String htmlTemplate = "HTMLConfirmationMailTemplate.vsl"; private String plainTemplate = "PlainConfirmationMailTemplate.vsl"; public ConfirmationMailGenerator(BasicUser user) { this.user = user; } public StringWriter generateHTML() throws Exception { Properties props = new Properties(); props.setProperty("resource.loader", "wepapp"); props.setProperty("webapp.resource.loader.class", "org.apache.velocity.tools.view.WebappResourceLoader"); props.setProperty("webapp.resource.loader.path", "/WEB-INF/mailtemplates/"); VelocityEngine engine = new VelocityEngine(props); VelocityContext context = new VelocityContext(); engine.init(); Map map = createDataModel(); context.put("user", map); Template template = engine.getTemplate(htmlTemplate); StringWriter writer = new StringWriter(); template.merge(context, writer); return writer; } ... }
The files is of course saved in /WEB-INF/mailtemplates/.
If I use this I get this error:
SEVERE: ResourceManager : unable to find resource 'HTMLConfirmationMailTemplate.vsl' in any resource loader. SEVERE: The log message is null.
Thank you for your time:)
回答1:
You are using the Webapp resourceloader, which is intended for pages served by the Velocity Tools servlet. (It requires some special initialization to find the root of the servlet context).
I recommend you use the ClasspathResourceLoader, then put the files into WEB-INF/classes, or elsewhere in your classpath. This is really the most straight forward approach.
resource.loader = class class.resource.loader.class = org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
More info is here:
https://velocity.apache.org/engine/1.7/apidocs/org/apache/velocity/runtime/resource/loader/ClasspathResourceLoader.html
回答2:
Will Glass answer is correct, but the configuration should be:
resource.loader = class class.resource.loader.class = org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
Note the class
at the beginning of the second line. See the links provided by him for more details!.
Note: Making an answer instead of a comment due to privileges.
回答3:
Velocity is probably using the class loader to find those files. I'd recommend putting them in WEB-INF/classes, which is in the CLASSPATH by default.
回答4:
I am fine it as follow,
In velocity.properties file
resource.loader=class, file class.resource.loader.class=org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader file.resource.loader.class=org.apache.velocity.runtime.resource.loader.FileResourceLoader file.resource.loader.path=vm_template runtime.log.logsystem.class=org.apache.velocity.runtime.log.SimpleLog4JLogSystem runtime.log.logsystem.log4j.category=velocity input.encoding=UTF-8 output.encoding=UTF-8
And at my java class
import java.io.StringWriter; import java.util.Properties; import org.apache.log4j.Logger; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.tools.generic.DateTool; import org.apache.velocity.tools.generic.EscapeTool; import org.apache.velocity.tools.generic.LoopTool; import org.apache.velocity.tools.generic.MathTool; import org.apache.velocity.tools.generic.NumberTool; import org.apache.velocity.tools.generic.SortTool; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; public class VelocitySupport implements InitializingBean { private static Logger log = Logger.getLogger(VelocitySupport.class); @Autowired private Properties properties; public final void afterPropertiesSet() throws Exception { location = location.replace("classpath:", ""); Resource res = new ClassPathResource(location); Properties prop = new Properties(); prop.load(res.getInputStream()); String staticDir = System.getProperty("staticDir"); String tempPath = prop.getProperty("file.resource.loader.path"); tempPath = staticDir + "/" + tempPath; prop.setProperty("file.resource.loader.path", tempPath); Velocity.init(prop); } public static String merge(final String template, final VelocityContext vc) throws Exception { try { vc.put("date", new DateTool()); vc.put("escape", new EscapeTool()); vc.put("math", new MathTool()); vc.put("number", new NumberTool()); vc.put("iterate", new LoopTool()); vc.put("sort", new SortTool()); Template temp = Velocity.getTemplate(template); StringWriter sw = new StringWriter(); temp.merge(vc, sw); sw.flush(); return sw.toString(); } catch (ResourceNotFoundException e) { log.error("", e); throw e; } catch (ParseErrorException e) { log.error("", e); throw e; } } private String location; public final void setLocation(final String location) { this.location = location; } }
And insert VM arguments of project as follow..
-DstaticDir= "your directory for template path"
That may be helpful for you...
回答5:
For resolving this error --WEB-INF/classes and all the JARs in WEB-INF/lib are in the CLASSPATH. Try moving your folder with the .vm files under WEB-INF/classes --dont put the abolute path eg. if abc.vm file is in /public_html/WEB-INF folder then put path = "/public_html/WEB-INF/abc.vm" for velocity template path.