2012-05-29 9 views
5

Estoy investigando el uso de FreeMarker para escribir archivos EDI. Estas son básicamente facturas electrónicas muy formateadas (y validadas). Decidí comenzar escribiendo un ejemplo simple y me quedé atrapado en la plantilla de 'pojo anidado'. Con esto quiero decir un POJO que contiene POJOs donde ambos tienen datos que quiero en mi salida. Escribí una prueba unitaria (independiente) que está fallando por un motivo desconocido. Cuando ejecuto la prueba obtengo la siguiente excepción:¿Cómo utilizar FreeMarker para la plantilla de Pojos anidados?

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> 

He intentado muchas variaciones en la plantilla y no he tenido éxito. Esta es la prueba:

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

} 

Gracias por cualquier ayuda!

Respuesta

9

Ha configurado la instancia TestPojo a sí misma como la raíz-modelo de datos, por lo que el user en user.getSub() es el String "Andy", que no tiene un método getSub. La plantilla correcta es "Welcome ${user}. Sub ${getSub().user}". Pero es mejor escribir como "Welcome ${user}. Sub ${sub.user}".

+0

Gracias. Había estado mirando esto tanto tiempo que me había convencido de que FreeMarker estaba equivocado. Tu respuesta es clara y muy apreciada. – Spina

Cuestiones relacionadas