freemarker 对象嵌套_如何使用FreeMarker模板化嵌套的Pojos?

在尝试使用FreeMarker创建EDI文件时,作者遇到一个问题,即无法正确模板化包含嵌套POJO的对象。具体表现为尝试访问`user.getSub().user`时,FreeMarker抛出`InvalidReferenceException`。单元测试显示,`user.getSub()`在模板中未定义。解决方案是,由于`user`是字符串,正确的模板写法应该是`"Welcome ${user}. Sub ${getSub().user}"`或者更简洁的`"Welcome ${user}. Sub ${sub.user}"`。
摘要由CSDN通过智能技术生成

bd96500e110b49cbb3cd949968f18be7.png

I'm investigating using FreeMarker to write EDI files. These are basically heavily formatted (and validated) electronic invoices. I decided to get started by writing a simple example and am stuck getting it to template a 'nested pojo'. By this I mean a POJO which contains POJOs where both of these have data I want in my output. I wrote a unit test (self contained) that is failing for an unknown reason. When I run the test I get the following exception:

Expression user.getSub is undefined on line 1, column 24 in simple.

The problematic instruction:

----------

==> ${user.getSub().user} [on line 1, column 22 in simple]

----------

Java backtrace for programmers:

----------

freemarker.core.InvalidReferenceException: Expression user.getSub is undefined on line 1, column 24 in simple.

at freemarker.core.TemplateObject.assertNonNull(TemplateObject.java:124)

at freemarker.core.TemplateObject.invalidTypeException(TemplateObject.java:134)

example.TestFreeMarkerTemplating.testSimpleTemplate(TestFreeMarkerTemplating.java:23)

I've tried many variations on the template, and haven't met success. This is the test:

package example;

import java.io.*;

import org.junit.Test;

import freemarker.cache.StringTemplateLoader;

import freemarker.ext.beans.BeansWrapper;

import freemarker.template.*;

import static org.junit.Assert.*;

public class TestFreeMarkerTemplating {

Configuration cfg = new Configuration();

StringTemplateLoader stringLoader = new StringTemplateLoader();

{ cfg.setTemplateLoader(stringLoader);

cfg.setObjectWrapper(new BeansWrapper()); }

@Test

public void testSimpleTemplate() throws TemplateException, IOException{

stringLoader.putTemplate("simple", "Welcome ${user}. Sub ${user.getSub().user}");

Template temp = cfg.getTemplate("simple");

StringWriter out = new StringWriter();

temp.process(new TestPojo(), out);

assertEquals("Welcome Andy. Sub Bill", out.toString());

}

public static class TestPojo {

private final String user = "Andy";

private final SubPojo sub = new SubPojo();

public String getUser() { return user; }

public SubPojo getSub() { return sub; }

}

public static class SubPojo {

private final String user = "Bill";

public String getUser() { return user; }

}

}

Thanks for any help!

解决方案

You have set the TestPojo instance itself as the data-model root, so the user in user.getSub() is the String "Andy", which doesn't have a getSub method. The correct template is "Welcome ${user}. Sub ${getSub().user}". But it's nicer to write as "Welcome ${user}. Sub ${sub.user}".

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值