我有一个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>
什么是这两段代码之间的区别? 有没有一种方法,以使第一段代码工作的Spring MVC中?
更新:
作为2.3.22有这个更简单的和非破坏性的解决方案:FreeMarker的配置,这样?api
作品,然后你可以使用的Java API的Map
,其中键是不是String
-s。 见这个FAQ条目或这个答案的更多细节。
和支柱的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)
bw = new BeansWrapper(); bw.setSimpleMapWrapper(true)
。 有了这个,方法Map
-s是不可见的,就像DefaultObjectWrapper
,所以你可以使用myMap.foo
和myMap[key]
安全。 但是,如果你很少需要得到的东西与非字符串键,你可以使用myMap(nonStringKey)
是的,有()
代替[]
这最后一个不工作DefaultObjectWrapper
。 (希望FreeMarker的2.4将解决这个烂摊子非字符串键废话,但它不喜欢它会掉很快...)
所以,接下来的问题就是如何设置与Spring的对象包装。 我不在家那里。 据我看到的,你有一个FreeMarkerConfigurer
豆具有freemarkerSettings
属性,它是一个Properties
多数民众赞成最终传递到的FreeMarker的对象Properties
为基础的配置API。 所以你应该能够添加object_wrapper
是指的类名属性ObjectWrapper
使用(或者它可能只是beans
使用默认BeansWrapper
比如像Struts的可能一样)。 问题在于,基于属性的API是相当有限的,所以你不能同时创建和配置(调用setSimpleMapWrapper
)一BeansWrapper
那里。 你可以做到这一点当然Spring配置文件中,但我不明白的方式来注入到FreeMarkerConfigurer
,除非你创建整个 freemarker.template.Configuration
对象作为一个bean,并注入该进FreeMarkerConfigurer
与configuration
它的属性。 因此,也许最简单的解决方法是扩大BeansWrapper
覆盖默认simpleMapWrapper
,然后通过参照类,延伸类的object_wrapper
。 (万一有人读这以后,它可能在FreeMarker 2.3.21,这样你可以设置将扩展属性配置API object_wrapper
到BeansWrapper() { simpleMapWrapper = true }
。)