将对象列表传递给 Freemarker,然后循环

2022-09-01 03:15:55

我一直在熟悉FreeMarker,一个Java的模板引擎。

我达到了能够通过哈希映射将对象传递到模板引擎的地步。这很好。但是,一旦我尝试将任何类型的多个对象集传递给FreeMarker,它就会给我一个freemarker.template.TemplateException,并抱怨它“预期的集合或序列。作业被评估为freemarker.template.SimpleHash”。

根据我在各种资源中阅读的内容,这是可以预料的。

现在,我已经完成了大部分的腿部工作,并发现很多人都在评论如何解决这个问题。但是,坦率地说,(a)对于许多例子来说,不清楚他们的建议在我的情况下究竟如何适用 - 即使我已经了解Java基础知识很长一段时间了,我对一些与Java Web应用程序有关的架构还很陌生,(b)我对哪种方法是最好的方法感到困惑。

我想做的,在最简化的层面上,基本上是这样的:

  1. 我有一个简单的Servlet。

  2. 我有一个简单的类(对于此示例,名为 Invoice),其中包含一些方法和属性。

  3. 我想让我的servlet(以某种方式)通过FreeMarker的处理方法呈现这些对象的实例(或这些对象的视图)的列表/数组/序列/哈希图。

  4. 我想让我的.ftl模板通过列表/数组/序列/哈希映射进行循环并显示方法结果,如下所示:

< # list invoices as invoice> 
Invoice note: ${invoice.getNote()}, Invoice Amount:${invoice.getAmount()} 
< / # list>

现在,我不一定在寻找快速和肮脏的解决方案。我是FreeMarker的新手,但我想以优雅和良好的设计的正确方式做到这一点。因此,我愿意完全重新思考这种方法。有人可以帮我看到我需要做些什么才能让这样的东西发挥作用吗?


答案 1

“工作”真的是一个集合吗?请在创建和处理模板的位置发布一段代码。

我刚刚写了一个快速测试来检查:

public void testFreeMarker() throws Exception {

    List<Invoice> invoices = Arrays.asList(
       new Invoice( "note1", "amount1" ), 
       new Invoice( "note2", "amount2" ) );
    Map<String, Object> root = new HashMap<String, Object>();
    root.put( "invoices", invoices );
    StringWriter out = new StringWriter();

    Configuration cfg = new Configuration();
    cfg.setClassForTemplateLoading( FreemarkerUtils.class, "/templates" );
    cfg.setObjectWrapper( new DefaultObjectWrapper() );
    Template temp = cfg.getTemplate( "listTest.ftl" );
    temp.process( root, out );

    System.out.println( out.getBuffer().toString() );
}

模板只是:

<#list invoices as invoice>
 Item: ${invoice.note} - ${invoice.amount}
</#list>

结果如预期:

Item: note1 - amount1
Item: note2 - amount2

答案 2

既是后续问题,也是可能偏离主题的答案。

问题:如何使发票列表可用于自由标记模板?你能发布代码片段,把它添加到请求/会话/任何东西吗?

可能偏离主题的答案:您是否考虑过使用Spring MVC?恕我直言,它使使用Freemarker作为网页模板化机制变得更加容易。它提供了一个FreemarkerViewRenderer,您可以从Web控制器方法返回“ModelAndView”...你可能想看看它。

http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/view.html#view-velocity


推荐