简体   繁体   English

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

[英]Using Freemarker to display a table of arbitrary Java objects and their fields

First, I've read this question , but it didn't resolve my issue. 首先,我已经阅读了这个问题 ,但是并没有解决我的问题。

I am trying to create a table that will display an arbitrary list of Java objects. 我正在尝试创建一个表,该表将显示Java对象的任意列表。 When I say "arbitrary" I mean both that the amount of objects is arbitrary and that the type of objects is arbitrary (they are all going to be instances of the same class though). 当我说“任意”时,我的意思是对象的数量是任意的,并且对象的类型是任意的(尽管它们都将是同一类的实例)。 I want the rows of this table to represent objects, and the columns to represent the value of each object's instance variable (spreadsheet style, basically). 我希望该表的行代表对象,而列则代表每个对象的实例变量(基本上是电子表格样式)的值。 The first row, however, will just be a list of instance variable names. 但是,第一行将只是实例变量名称的列表。

The objects I am currently testing this on has all variables set to private, but I have provided the relevant getters and setters. 我目前正在测试的对象的所有变量都设置为private,但是我提供了相关的getter和setter。

Here is a snippet from my Java code. 这是我的Java代码的摘录。 I am pulling objects from an Oracle Coherence cache, and putting them into an ArrayList. 我正在从Oracle Coherence缓存中提取对象,并将其放入ArrayList中。 Then I make a string array of the instance variable names.: 然后,我创建一个实例变量名称的字符串数组:

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

Here is a snippet from the relevant .ftl file: 以下是相关.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>

This gets me the following error: 这使我出现以下错误:


freemarker.core.InvalidReferenceException: The following has evaluated to null or missing: ==> bean[colName] [in template "front.ftl" at line 46, column 35] freemarker.core.InvalidReferenceException:以下内容评估为空或丢失:==> bean [colName] [在模板“ front.ftl”的第46行第35列中]

Tip: It's the final [] step that caused this error, not those before it. 提示:导致此错误的是[[]最后一步,而不是之前的错误。

Tip: If the failing expression is known to be legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing. 提示:如果已知失败的表达式合法地引用了有时为空或缺失的内容,请指定默认值,例如myOptionalVar!myDefault,或使用<#if myOptionalVar ??> when-present <#else> when-missing。 (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)?? FTL stack trace ("~" means nesting-related): - Failed at: ${bean[colName]} [in template "front.ftl" at line 46, column 33] (这些仅覆盖表达式的最后一步;要覆盖整个表达式,请使用括号:(myOptionalVar.foo)!myDefault,(myOptionalVar.foo)?? FTL堆栈跟踪(“〜”表示与嵌套相关):-失败位于:$ {bean [colName]} [在第46行第33列的模板“ front.ftl”中]

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

The problem seems to be my ftl syntax; 问题似乎出在我的ftl语法上。 that is, it doesn't like the expression ${bean[colName]}. 也就是说,它不喜欢表达式$ {bean [colName]}。

Questions: 问题:

1) Is the syntax wrong? 1)语法错误吗?

2) Is this something that Freemarker can't do? 2)这是Freemarker无法做的事情吗?

3) Should I try another approach? 3)我应该尝试其他方法吗? For example, should I just create an array with each bucket containing an array (or another data structure) of the instance variable values? 例如,是否应该仅创建一个包含每个实例变量值数组(或其他数据结构)的存储桶的数组?

It should work, providing that: 它应该工作,并提供:

  • Pof is a public class Pof是公共类
  • There's a public Pof.getFoo() method for each colName "foo" 每个colName "foo"都有一个公共的Pof.getFoo()方法。
  • getFoo() returns non- null value. getFoo()返回非null值。 If it sometimes returns null , you have to specify what to display then, for example: ${bean[colName]!'-'} 如果有时返回null ,则必须指定显示的内容,例如: ${bean[colName]!'-'}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM