2016-08-04 23 views
0

Zuerst habe ich this question gelesen, aber es hat mein Problem nicht gelöst.Verwenden von Freemarker zum Anzeigen einer Tabelle von beliebigen Java-Objekte und ihre Felder

Ich versuche, eine Tabelle zu erstellen, die eine beliebige Liste von Java-Objekten anzeigen wird. Wenn ich "willkürlich" sage, meine ich sowohl, dass die Anzahl der Objekte willkürlich ist als auch dass der Typ der Objekte beliebig ist (sie werden alle Instanzen derselben Klasse sein). Ich möchte, dass die Zeilen dieser Tabelle Objekte darstellen und die Spalten den Wert der Instanzvariablen jedes Objekts darstellen (im Wesentlichen Tabellenkalkulation). Die erste Zeile ist jedoch nur eine Liste von Instanzvariablennamen.

Die Objekte, die ich gerade teste, haben alle Variablen auf privat gesetzt, aber ich habe die relevanten Getter und Setter zur Verfügung gestellt.

Hier ist ein Ausschnitt aus meinem Java-Code. Ich ziehe Objekte aus einem Oracle Coherence-Cache und lege sie in eine ArrayList. Dann mache ich einen String-Array der Instanzvariablennamen .:

 /** 
    * Get objects in cache and add to ArrayList. 
    */ 

    for(Iterator iter = currentCache.entrySet().iterator();iter.hasNext();){ 
     Map.Entry entry = (Map.Entry)iter.next(); 
     String key = (String) entry.getKey(); 
     Pof tempPof = (Pof)entry.getValue(); 
     tableList.add(tempPof); 
     System.out.println("one loop"); 
    } 

    request.setAttribute("beans",tableList); 

    System.out.println("Size of tableList is: " + tableList.size()); 
    /** 
    * Build an array containing the variable names of cached objects. 
    */ 

    Field[] fields = Pof.class.getDeclaredFields(); 
    String[] variableNames = new String[fields.length]; 

    for(int j = 0; j < fields.length;j++){ 
     variableNames[j] = fields[j].getName(); 
     System.out.println(variableNames[j]); 
    } 

    request.setAttribute("colNames",variableNames); 


    /** 
    * numCols determines the number of columns displayed in the table. 
    */ 

    int numCols = fields.length; 
    String[] fieldStrings = new String[numCols]; 
    request.setAttribute("numCols",numCols); 
    Pof thing = (Pof) tableList.get(0); 

Hier ist ein Ausschnitt aus der jeweiligen .ftl Datei:

<table border = "1px"> 
     <thead> 
      <tr> 
       <th colspan="${numCols}">${selectedCache}</th> 
      </tr> 
      <tr> 
       <#list colNames as colName> 
        <td>${colName}</td> 
       </#list> 
      </tr> 
     </thead> 
     <tbody> 
      <#list beans as bean> 
       <tr> 
        <#list colNames as colName> 
         <td>${bean[colName]}</td> 
        </#list> 
       </tr> 
      </#list> 
     </tbody> 

    </table> 

Dies wird mir die folgende Fehlermeldung:


freemarker.core.InvalidReferenceException: Folgendes wurde zu null oder fehlend ausgewertet: ==> bean [colName] [in Vorlage "front.ftl" in Zeile 46, Spalte 35]

Tipp: Es ist der letzte [] Schritt, der diesen Fehler verursacht hat, nicht die vorherigen.

Tipp: Wenn die fehlerhafte Expression ist bekannt, rechtlich auf etwas beziehen sein, die manchmal null ist oder fehlt, entweder einen Standardwert wie myOptionalVar myDefault angeben, oder verwenden Sie < #if myOptionalVar ??> wenn präsenten < #else> wenn-fehlend. (Diese decken nur den letzten Schritt des Ausdrucks ab; um den gesamten Ausdruck abzudecken, verwenden Sie Klammern: (myOptionalVar.foo)! MyDefault, (myOptionalVar.foo) ?? FTL-Stack-Trace ("~" bedeutet Verschachtelung-bezogen): - fehlgeschlagen bei $ {bean [colName]} [in Vorlage "front.ftl" in Zeile 46, Spalte 33]

at freemarker.core.InvalidReferenceException.getInstance(InvalidReferenceException.java:134) 
at freemarker.core.EvalUtil.coerceModelToTextualCommon(EvalUtil.java:451) 
at freemarker.core.EvalUtil.coerceModelToStringOrMarkup(EvalUtil.java:374) 
at freemarker.core.DollarVariable.calculateInterpolatedStringOrMarkup(DollarVariable.java:96) 
at freemarker.core.DollarVariable.accept(DollarVariable.java:59) 
Truncated. see log file for complete stacktrace 

Das Problem scheint meine FTL Syntax zu sein, das heißt, es doesn ‚t mag den Ausdruck $ {bean [colName]}

Fragen:.

1) Ist die Syntax falsch?

2) Ist das etwas, was Freemarker nicht tun kann?

3) Sollte ich einen anderen Ansatz versuchen? Soll ich beispielsweise ein Array erstellen, in dem jeder Bucket ein Array (oder eine andere Datenstruktur) der Werte der Instanzvariablen enthält?

Antwort

0

sollte es funktionieren, dass die Bereitstellung von:

  • Pof ist eine öffentliche Klasse
  • davon entfallen auf jeden null Wert nicht colName"foo"
  • getFoo() kehrt eine öffentliche Pof.getFoo() Methode ist. Wenn es manchmal null zurückgibt, müssen Sie angeben, was dann angezeigt werden soll, zum Beispiel: ${bean[colName]!'-'}
+0

Das hat meine Tabelle generiert! Aber es gibt viele Nullfelder. Wenn ich die Werte der Objekte, die ich an FreeMarker sende, überprüfe, sind sie nicht null. Es scheint kein Muster zu geben, das den Variablentypen oder Werten folgt. Aber ich habe bemerkt, dass die Variablen, die null zurückgegeben haben, mit einem einzelnen Großbuchstaben begonnen haben (zB "Big_Contracts"), während die Instanzvariablen, auf die FreeMarker erfolgreich zugegriffen hat, mit zwei Großbuchstaben anfingen (zB "LG_Contracts"). Hat FreeMarker etwas mit dem Fall dieser Strings zu tun, wenn Daten aus einem Hash abgerufen werden? – murdoc1871

+0

FreeMarker kümmert sich nicht um Felder (gut, es kann konfiguriert werden, öffentliche Felder zu lesen, aber das ist jetzt off topic). Es kümmert sich um JavaBeans-Eigenschaften. Daher werden die Variablennamen aus den Getter-Methodennamen gemäß den Regeln abgeleitet, die durch die JavaBeans-Spezifikation spezifiziert sind. Für 'getBigContacts' lautet der Name der Eigenschaft' bigContacts'. Seltsamerweise ist für 'getLGContacts()' der Name der Eigenschaft 'LGContacts' ... Diese Regeln werden nicht von FreeMarker definiert, sondern von der JavaBeans-Spezifikation. – ddekany