Apache Velocity:是否有从命令行验证模板正确性的标准方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1910857/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Apache Velocity: Is there a standard way of verifying the correctness of a template from the command line?
提问by braveterry
Our website uses the Apache Velocitytemplate language. Our Content Management System already checks any generated XML documents for well-formedness. We've been asked to check documents to catch Velocity syntax errors before pushing the files to the live site.
我们的网站使用Apache Velocity模板语言。我们的内容管理系统已经检查了所有生成的 XML 文档的格式是否正确。我们被要求在将文件推送到实时站点之前检查文档以捕获 Velocity 语法错误。
Is there a standard way of verifying the correctness of a Velocity template from the command line?
是否有从命令行验证 Velocity 模板正确性的标准方法?
I am prepared to read in the template path, initialize the Velocity Engine, parse the template, and capture any errors as shown on this page, but if there's a ready made tool that takes a file and a configuration, and spits out any errors, then I'd rather use that.
我准备读入模板路径,初始化 Velocity 引擎,解析模板,并捕获任何错误,如本页所示,但如果有一个现成的工具,它需要一个文件和一个配置,并吐出任何错误,那么我宁愿使用它。
Update
更新
Here's what I ended up doing:
这是我最终做的:
package velocitysample;
import java.io.IOException;
import java.io.StringWriter;
import org.apache.log4j.Logger;
import org.apache.log4j.BasicConfigurator;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.Template;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.MethodInvocationException;
public class Main
{
/** Define a static logger variable so that it references the Logger
* instance named "MyApp".
*/
private static Logger logger = Logger.getLogger(Main.class);
/**
* @param args the command line arguments
*/
public static void main(String[] args)
{
/* Set up a simple log4j configuration that logs on the console. */
BasicConfigurator.configure();
/* Check to see that a template path was passed on the command line. */
if (args.length != 1)
{
logger.fatal("You must pass the path to a template as a " +
"command line argument.");
return;
}
/* Pull the template filename from the command line argument. */
String fileName = args[0];
try
{
Velocity.setProperty("resource.loader", "file");
Velocity.setProperty("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.FileResourceLoader");
Velocity.setProperty("file.resource.loader.path", "/templates/");
Velocity.setProperty("file.resource.loader.cache", "false");
Velocity.setProperty("file.resource.loader.modificationCheckInterval", "0");
Velocity.init();
}
catch (Exception ex)
{
logger.fatal("Error initializing the Veolcity engine.", ex);
return;
}
boolean error = false;
/* Create an empty Velocity context */
VelocityContext context = new VelocityContext();
Template template = null;
try
{
template = Velocity.getTemplate(fileName);
}
catch( ResourceNotFoundException rnfe )
{
logger.error("Couldn't find the template to parse at this path: " +
fileName + ".", rnfe);
error = true;
}
catch( ParseErrorException peex )
{
logger.error("Error parsing the template located at this path: " +
fileName + ".", peex);
error = true;
}
catch( MethodInvocationException mie )
{
logger.error("Something invoked in the template (" + fileName +
") threw an Exception while parsing.", mie);
error = true;
}
catch( Exception e )
{
logger.error("An unexpected exception was thrown when attempting " +
"to parse the template: " + fileName + ".", e);
error = true;
}
if (error)
{
return;
}
StringWriter sw = new StringWriter();
try
{
template.merge(context, sw);
}
catch (ResourceNotFoundException rnfe)
{
logger.error("Couldn't find the template to merge at this path: " +
fileName + ".", rnfe);
error = true;
}
catch (ParseErrorException peex)
{
logger.error("Error parsing the template at this path during merge: " +
fileName + ".", peex);
error = true;
}
catch (MethodInvocationException mie)
{
logger.error("Something invoked in the template (" + fileName +
") threw an Exception while merging.", mie);
error = true;
}
catch (IOException ioe)
{
logger.error("Error reading the template located at this path from " +
"disk: " + fileName + ".", ioe);
error = true;
}
catch( Exception e )
{
logger.error("An unexpected exception was thrown when attempting " +
"to merge the template: " + fileName + ".", e);
error = true;
}
if (!error)
{
logger.info("No syntax errors detected.");
}
}
}
采纳答案by ZZ Coder
There is a tool distributed with Velocity called TemplateTool, which dumps all the references and it can be used to validate the syntax of the template.
有一个与 Velocity 一起分发的工具,称为 TemplateTool,它可以转储所有引用,并可用于验证模板的语法。
However, you must have the context setup correctly to verify any template. So the best verification is to write your own tool with your own context.
但是,您必须正确设置上下文才能验证任何模板。所以最好的验证是用你自己的上下文编写你自己的工具。
回答by Will Glass
To catch Velocity syntax errors, your approach is probably the best.
要捕获 Velocity 语法错误,您的方法可能是最好的。
However, it will ignore invalid macro arguments and non-existent references. In Velocity 1.6 there is a strict mode that you can set which will throw an exception for bad macro parameters (e.g. the wrong number) or for bad references (e.g. $abc.badMethod() ). This assumes you are populating the context of the templates used in your testing tool the same as when the templates are used in production.
但是,它将忽略无效的宏参数和不存在的引用。在 Velocity 1.6 中,您可以设置一个严格模式,它会针对错误的宏参数(例如错误的数字)或错误的引用(例如 $abc.badMethod() )抛出异常。这假设您填充测试工具中使用的模板的上下文与模板在生产中使用时相同。
回答by Claes
In December 2010 someone published a tool for validating Velocity. I tried it out and it works fine. It uses Velocity 1.6.4, but maybe that can be swapped out for a different version if needed.
2010 年 12 月,有人发布了一个验证 Velocity 的工具。我试过了,效果很好。它使用 Velocity 1.6.4,但如果需要,也许可以将其换成不同的版本。

