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)
<snip>
example.TestFreeMarkerTemplating.testSimpleTemplate(TestFreeMarkerTemplating.java:23)
<snip>
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!
Apache FreeMarker is a free Java-based template engine, originally focusing on dynamic web page generation with MVC software architecture. However, it is a general purpose template engine, with no dependency on servlets or HTTP or HTML, and is thus often used for generating source code, configuration files or e-mails.
FreeMarker is a template engine, written in Java, and maintained by the Apache Foundation.
The most common method of detecting for empty or null values uses the has_content function and the trim function. The has_content function is often used with another built-in FreeMarker function to detect for null values. Check the FreeMarker documentation for more information on the has_content function.
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}"
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With