我使用Spring Boot和Freemarker启动器。
给出以下字符串:
<h2>${fragment.title}</h2>
我正在尝试对此String执行一些验证,以确保它包含正确的Freemarker语法。
我尝试使用以下代码执行此操作:
@Autowired
private Configuration configuration;
private void validateTemplate(Fragment fragment) {
try {
ModelAndView model = new ModelAndView();
model.addObject("fragment", fragment);
StringTemplateLoader stringLoader = new StringTemplateLoader();
stringLoader.putTemplate("template", fragment.getDesign());
configuration.setTemplateLoader(stringLoader);
configuration.setDefaultEncoding("UTF-8");
Template template = configuration.getTemplate("template");
template.process(model, new OutputStreamWriter(System.out));
} catch (Exception e) {
// failed validation...
}
}
上述字符串应该验证,因为fragment
不为空。但是抛出了以下错误:
2017-11-19 11:11:11.732 ERROR 4956 --- [-nio-443-exec-8] freemarker.runtime:执行FreeMarker时出错 模板
freemarker.core.InvalidReferenceException:已评估以下内容 为null或缺失: ==&GT;片段[在模板“模板”第1行第7列]
----提示:如果已知失败的表达式合法地引用有时为null或缺失的内容,则指定默认表达式 像myOptionalVar!myDefault这样的值,或者使用&lt; #if myOptionalVar ??&gt;在至今&LT;#其他&gt;在缺失。 (仅限这些 涵盖表达的最后一步;覆盖整个表达,
使用括号:(myOptionalVar.foo)!myDefault,(myOptionalVar.foo)??
---- FTL堆栈跟踪(“〜”表示与嵌套相关): - 失败于:$ {fragment.title} [在第1行第5栏的模板“模板”中] ---- at freemarker.core.InvalidReferenceException.getInstance(InvalidReferenceException.java:134) 〜[freemarker-2.3.25-incubating.jar:2.3.25] at freemarker.core.UnexpectedTypeException.newDesciptionBuilder(UnexpectedTypeException.java:80) 〜[freemarker-2.3.25-incubating.jar:2.3.25] at freemarker.core.UnexpectedTypeException。(UnexpectedTypeException.java:43) 〜[freemarker-2.3.25-incubating.jar:2.3.25] at freemarker.core.NonHashException。(NonHashException.java:49) 〜[freemarker-2.3.25-incubating.jar:2.3.25] at freemarker.core.Dot._eval(Dot.java:48) 〜[freemarker-2.3.25-incubating.jar:2.3.25] at freemarker.core.Expression.eval(Expression.java:81) 〜[freemarker-2.3.25-incubating.jar:2.3.25] at freemarker.core.DollarVariable.calculateInterpolatedStringOrMarkup(DollarVariable.java:96) 〜[freemarker-2.3.25-incubating.jar:2.3.25] at freemarker.core.DollarVariable.accept(DollarVariable.java:59) 〜[freemarker-2.3.25-incubating.jar:2.3.25] at freemarker.core.Environment.visit(Environment.java:327) [freemarker-2.3.25-incubating.jar:2.3.25] at freemarker.core.Environment.visit(Environment.java:333) [freemarker-2.3.25-incubating.jar:2.3.25] at freemarker.core.Environment.process(Environment.java:306) [freemarker-2.3.25-incubating.jar:2.3.25] at freemarker.template.Template.process(Template.java:386) [freemarker的-2.3.25-incubating.jar:2.3.25]
我的设置中缺少什么导致Freemarker不“看到”fragment
?
答案 0 :(得分:1)
获取Template
对象本身就足以进行语法验证。验证模板是否会在运行时失败可能会非常棘手,具体取决于应用程序,因为您需要一个类似于真实数据模型的数据模型。
但是,假设您可以在您的案例中提供此类数据模型。那么问题是ModelAndView
不是你的模型。正如其名称所示,您可以建模和查看。它里面只包含你的模型。 (FreeMarker不依赖于Spring,因此只需将该对象用作通用JavaBean,因此您的变量将是ModeAndView
对象本身的JavaBean属性。)尝试将ModelAndView.getModel()
传递给{{ 1}}而不是。 (我不是100%确定是否总能显示所有模型变量,但我想是这样。无论如何,它扩展Template.process
,FreeMarker会识别,并将使用java.util.Map
来解析变量。)