我正在Java项目中使用Freemarker。
到目前为止,一切都很好。
[我已经将POJO转换为JSONObject,并且在我的.ftl文件中,我能够从POJO中提取变量名并可以正常工作,除了其中之一。
我的POJO如下:(伪)
Response.class
name (String);
dob (String);
Collection<Contact> contacts;
Collection<Database> databases;
它包含以下POJO的集合:
Contact.java
firstName(String);
surname(String);
Database.java
username(String);
password(String);
query(String);
到目前为止,可以从“数据库”中访问任何内容;我已经能够说:
<#assign databases = jsonObject.databases>
<#list 0 ..< databases.length() as i>
jdbc_user=>"${databases.get(i).username}" **(works fine!)**
jdbc_password=>"${databases.get(i).password}" **(works fine!)**
statement => "${databases.get(i).query} and date > :sql_last_value" **(doesn't work)**
</#list>
我会说一个错误
For "${...}" content: Expected a string or something automatically convertible to string
并且它以${databases.get(i).query}
为问题的原因
我已经意识到这可能是因为“查询”是Freemarker保留的一些顶级变量;当我回到Database.class时,我将“查询”更改为“ query1”,并将.ftl文件更改为${databases.get(i).query1}
,没有问题
TLDR;我认为我需要以某种方式转义/引用“查询”,以便将其理解为POJO变量名称。我已经尝试过.vars [query],但是我从JSON库得到一个异常,说没有与jsonObject.get(vars)匹配的东西。
编辑:我仅假设“查询”是某种保留字;但无法找到证实了这一点的文档
我不知道JSONObject
的API,所以我在下面猜测...该类在哪个库/包中? (例如,它看起来不像org.json.JSONObject
。)
query
在FreeMarker本身中未保留。问题必须是用作JSONObject
的ObjectWrapper
无法识别freemarker.template.Configuration.objectWrapper
类(可能您使用的是默认值),因此它只是回退以将该类的Java API公开为模板,是。我想query
是JSONObject
类中的方法,并且您无法打印方法(但可以调用它)。当您引用一个不存在的类成员时,例如username
,那么ObjectWrapper
肯定会回退调用someJSONObject.get("username")
,这就是为什么您会以某种方式误以为它可以理解JSON。但事实并非如此,这只是一般的备用。因此,由于query
方法隐藏了速记,因此您必须求助于databases.get(i).get("query")
。
如果您将大量使用这些JSON对象,请考虑开发一个自定义ObjectWrapper
,它将这些对象很好地展示给FreeMarker。 (然后,您将不会遇到这些阴影问题,您可以只写<#list databases as database>
而不是处理索引等)。
或者,也许您不将POJO-s转换为JSON,根据它们的API,最好在模板中处理它们。