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

发布于 2024-11-07 04:38:32 字数 1008 浏览 0 评论 0原文

我已经熟悉了 FreeMarker,一个 Java 模板引擎。

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

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

现在,我已经做了很多工作,并发现很多人都在评论如何解决这个问题。但是,坦率地说,(a) 对于许多示例,并不清楚他们的建议到底如何适用于我的案例——尽管我已经了解 Java 基础知识相当长一段时间了,但我对某些架构还很陌生与 Java Web 应用程序相关,并且 (b) 我对哪种方法是最好的方法感到困惑。

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

  1. 我有一个简单的 Servlet。

  2. 我有一个简单的类(对于本示例,名为 Invoice),带有一些方法和属性。

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

  4. 我想让我的 .ftl 模板循环遍历列表/数组/序列/哈希图并显示方法结果,如下所示:

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

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

I've been acquainting myself with FreeMarker, a template engine for Java.

I got to the point where I am able to pass an object to the template engine through a Hash Map. That works alright. But as soon as I try to pass any sort of set of multiple objects to FreeMarker it gives me a freemarker.template.TemplateException and complains that it "Expected collection or sequence. jobs evaluated instead to freemarker.template.SimpleHash".

From what I understand from reading up on this in the various resources, this is to be expected.

Now, I have done much of the leg work and found a number of people commenting on how to get around this. But, quite frankly, (a) for many of the examples it was unclear as to how exactly their advice applies in my case--even though I've known Java basics for quite a while I'm pretty new to some of the architecture pertaining to Java web apps and (b) I'm confused as to which of the approaches was the best approach.

All I want to do, at the most simplified level, is basically this:

  1. I have a simple Servlet.

  2. I have a simple class (for this example named Invoice) with a few methods and properties.

  3. I want to have my servlet (in some fashion) present a list/array/sequence/hashmap of instances of these objects (or views of those objects) via FreeMarker's process method.

  4. I want to have my .ftl template do a loop through the list/array/sequence/hashmap and display method results, something like this:

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

Now, I'm not necessarily looking for the quick & dirty solution to this. I'm new to FreeMarker, but I want to do this in the proper way that is elegant and good design. So I'm open to completely rethinking this approach. Can someone help me see what I need to do to get something like this to work?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

深海少女心 2024-11-14 04:38:32

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

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

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

Is "jobs" really a collection? Please post a snippet of code where you are creating and processing your template.

I just wrote a quick test to check:

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() );
}

The template is just:

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

The result is as expected:

Item: note1 - amount1
Item: note2 - amount2
打小就很酷 2024-11-14 04:38:32

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

问题:
如何使您的发票清单可供 freemarker 模板使用?您可以发布将其添加到请求/会话/其他内容的代码片段吗?

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

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

Both a follow-up question and a possibly off-topic answer..

The question:
How do you make your invoice list available to the freemarker template? Could you post the code snippet where you add it to the request / session / whatever?

The possibly off-topic answer:
Have you considered using Spring MVC? Imho it makes working with Freemarker as a web page templating mechanism somewhat easier. It provides a FreemarkerViewRenderer and you can just return a "ModelAndView" from your web controller methods... you might want to have a look at it.

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文