更新: 2.3.22 以降では、?api
これを回避するために使用する必要があります。詳細については、この回答またはこの FAQ エントリを参照してください。
古い答え:
Map
ここでの問題の根本は、FreeMarker テンプレート言語に Javaの型に相当するものがないことです。代わりに、に似た「ハッシュ」と呼ばれるタイプを持ちますが、Map
文字列キー (元々は変数名) しかサポートしていません。fh[key]
そのため、 が表示されると、key
が文字列値 (この場合は POJO のラップ方法による の結果) を持っていると見なされるkey.toString()
ため、アイテムが見つかりません。したがって、解決策は、[]
文字列以外のキーに演算子を使用するのではなく、Java API を使用することMap.get(Object key)
です。
そして残りは時代遅れです...
しかし、それを行おうとすると、さらに別の障害に遭遇します: デフォルトでは-sObjectWrapper
のメソッドが公開されません。これは、 の文字列キーが既に同じ名前空間に取り込まれているためです。他のさまざまな理由からデフォルトも嫌いなので、常に FreeMarker を次のように設定します。Map
Map
ObjectWrapper
BeansWrapper wrapper = new BeansWrapper();
wrapper.setSimpleMapWrapper(true);
cfg.setObjectWrapper(wrapper);
このラッパーを使用すると、 Map
-s を asmyMap[someStringKey]
または asの両方で使用できますmyMap(whateverKey)
。したがって、あなたの場合は${fh(key)}
. 繰り返しますが、これはデフォルトでは機能しませんObjectWrapper
。
さらに悪いことに、ここで W3C DOM を使用しているようです。上記のラッパーはNode
、FreeMarker XML 機能を使用できるように -s を自動的にラップしません。したがって、それが必要な場合は、DOM ノードを常に手動でラップしない限り、DOM ノードBeansWrapper
を認識するように拡張する必要があります。幸いなことに、それは簡単です。
public class MyObjectWrapper extends freemarker.ext.beans.BeansWrapper {
public TemplateModel wrap(Object obj) throws TemplateModelException {
if (obj instanceof org.w3c.dom.Node) {
return freemarker.ext.dom.NodeModel.wrap((org.w3c.dom.Node) obj);
} else {
return super.wrap(obj);
}
}
}
FreeMarker を使用している環境にすでにカスタムObjectWrapper
. その場合は、どうにかしてそれを拡張してみてください...