如何处理Freemarker String模板?

时间:2017-11-19 11:22:08

标签: java freemarker

我使用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

1 个答案:

答案 0 :(得分:1)

获取Template对象本身就足以进行语法验证。验证模板是否会在运行时失败可能会非常棘手,具体取决于应用程序,因为您需要一个类似于真实数据模型的数据模型。

但是,假设您可以在您的案例中提供此类数据模型。那么问题是ModelAndView不是你的模型。正如其名称所示,您可以建模和查看。它里面只包含你的模型。 (FreeMarker不依赖于Spring,因此只需将该对象用作通用JavaBean,因此您的变量将是ModeAndView对象本身的JavaBean属性。)尝试将ModelAndView.getModel()传递给{{ 1}}而不是。 (我不是100%确定是否总能显示所有模型变量,但我想是这样。无论如何,它扩展Template.process,FreeMarker会识别,并将使用java.util.Map来解析变量。)