1

私は HashMap を持っていMap<Long, List<Map<String, Object>>> typeAndKnoます。FreeMarker ページでは、このマップのコンテンツを次のように取得します。

<#list typeAndKno?keys as typeId>
    ${typeAndKno.get(typeId).get(0).get('TYPE_NAME')}
    <#list typeAndKno.get(typeId) as kno>
         ${kno.get('KNOWLEDGE_ID')}
    </#list>
</#list>

このコードは Struts2 では問題なく動作しますが、Spring MVC に移行した後、コードは失敗します。最終的にコードを次のように変更しました。

<#list typeAndKno?keys as typeId>
    ${typeAndKno[typeId]?first['TYPE_NAME']}
    <#list typeAndKno[typeId?string] as kno>
         ${kno['KNOWLEDGE_ID']}
    </#list>
</#list>

これら 2 つのコードの違いは何ですか? Spring MVC で最初のコードを機能させる方法はありますか?

4

1 に答える 1

2

アップデート:

2.3.22 の時点で、これにははるかに簡単で中断のない解決策があります。それが機能するように FreeMarker を構成すると、キーが-sでない場所?apiの Java API を使用できます。詳細については、この FAQ エントリまたはこの回答を参照してください。MapString

また、Strut の FreeMarker セットアップは、現在では強く推奨されていません。もちろん、彼らがそれを行った当時、それはおそらく最も合理的な回避策でしたが、しばらくの間、特に 2.3.22 以降ではそうではありません。

古い答え(時代遅れ):

テンプレートから Java オブジェクトを表示する方法は、ObjectWrapper使用されている FreeMarker 構成設定によって異なります。あなたの例に基づいて、StrutsはBeansWrapperデフォルト設定でを使用しますが、SpringはおそらくDefaultObjectWrapper. そのため、違いが生じます。次の理由から、どちらの使用もお勧めしません。

  • BeansWrapperデフォルト設定でMapは、キーはメソッド名と混在し、メソッド名が優先されます。確かにそれを回避するために を安全に使用できますがmyMap.get(key)myMap.get('foo')と比較するとひどいものmyMap.fooであり、 と呼ばれるメソッドがない場合にのみ機能しますfoo。また?keys、実際のキーとメソッド名の混合物を返します...それは混乱です。

  • DefaultObjectWrapper安全に書くことができますが、文字列のみをサポートしてmyMap.fooいるため、文字列以外のキーを持つエンティティを取得することはできず、もうありません。myMap[key]myMag.get(key)

したがって、私が通常 FreeMarker で使用したのはbw = new BeansWrapper(); bw.setSimpleMapWrapper(true). これにより、 と同様に -s のメソッドがMap見えなくなり、安全にDefaultObjectWrapper使用できます。ただし、文字列以外のキーで何かを取得する必要がめったにない場合は、(yes, with instead of ) を使用できます。この最後は では機能しません。(願わくば、FreeMarker 2.4 が非文字列キーによるこの混乱をナンセンスに解決してくれることを願っていますが、すぐに公開されるとは思えません...)myMap.foomyMap[key]myMap(nonStringKey)()[]DefaultObjectWrapper

ということで、次の質問はSpringでオブジェクトラッパーを設定する方法です。私は家にいません。私が見る限り、プロパティFreeMarkerConfigurerを持つ Bean があります。これは、最終的に FreeMarkerベースの構成 APIに渡されるオブジェクトです。したがって、使用するクラス名を参照するプロパティを追加できるはずです(または、Struts のようにデフォルトのインスタンスを使用することもできます)。問題は、プロパティベースの API がかなり制限されているため、作成と構成 (呼び出し) の両方ができないことです。もちろん、春の構成ファイルでそれを行うこともできますが、全体を作成しない限り、それをに注入する方法はわかりませんfreemarkerSettingsPropertiesPropertiesobject_wrapperObjectWrapperbeansBeansWrappersetSimpleMapWrapperBeansWrapperFreeMarkerConfigurer freemarker.template.ConfigurationFreeMarkerConfigurerオブジェクトを Bean として、そのプロパティを使用して に注入しconfigurationます。したがって、おそらく最も簡単な回避策はBeansWrapper、デフォルトの をオーバーライドするように拡張し、simpleMapWrapperを介してその拡張クラスのクラスを参照することobject_wrapperです。(誰かが後でこれを読んだ場合に備えて、FreeMarker 2.3.21 がプロパティ構成 API を拡張して、 に設定できるようにする可能性がありますobject_wrapperBeansWrapper() { simpleMapWrapper = true })

于 2013-08-28T15:05:16.297 に答える