使用Freemarker显示任意Java对象及其字段的表

时间:2016-08-04 20:54:18

标签: java freemarker

首先,我已阅读this question,但它并未解决我的问题。

我正在尝试创建一个显示任意Java对象列表的表。当我说"任意"我的意思是对象的数量是任意的,对象的类型是任意的(尽管它们都是同一个类的实例)。我希望此表的行表示对象,并希望列表示每个对象的实例变量的值(基本上是电子表格样式)。但是,第一行只是实例变量名称列表。

我正在测试此对象的对象将所有变量设置为私有,但我提供了相关的getter和setter。

这是我的Java代码的片段。我从Oracle Coherence缓存中提取对象,并将它们放入ArrayList中。然后我创建一个实例变量名的字符串数组。:

        /**
     * 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);

以下是相关.ftl文件的摘录:

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

这会给我带来以下错误:

freemarker.core.InvalidReferenceException:以下内容已评估为null或缺失: ==&GT; bean [colName] [在模板&#34; front.ftl&#34;在第46行,第35栏

提示:导致此错误的最终[]步骤不是之前的错误。

提示:如果已知失败的表达式在法律上是指某些有时为null或缺失的内容,请指定默认值,如myOptionalVar!myDefault,或使用&lt; #if myOptionalVar ??&gt; - 当 - 本&LT;#其他&gt;在缺失。 (这些仅涵盖表达式的最后一步;要覆盖整个表达式,请使用括号:(myOptionalVar.foo)!myDefault,(myOptionalVar.foo)?? FTL堆栈跟踪(&#34;〜&#34;表示与嵌套相关):      - 失败于:$ {bean [colName]} [在模板&#34; front.ftl&#34;在第46行,第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

问题似乎是我的ftl语法;也就是说,它不喜欢表达式$ {bean [colName]}。

问题:

1)语法错了吗?

2)这是Freemarker无法做到的事情吗?

3)我应该尝试另一种方法吗?例如,我是否应该创建一个数组,每个存储桶包含实例变量值的数组(或其他数据结构)?

1 个答案:

答案 0 :(得分:0)

它应该有用,提供:

  • Pof是一个公共类
  • 每个Pof.getFoo() colName
  • 都有公开"foo"方法
  • getFoo()返回非null值。如果有时会返回null,则必须指定要显示的内容,例如:${bean[colName]!'-'}