更新:
从 2.3.22 开始,有一个更简单且无中断的解决方案:配置 FreeMarker 以使其?api
工作,然后您可以使用Map
密钥不是String
-s 的 Java API。有关更多详细信息,请参阅此常见问题解答条目或此答案。
现在强烈反对使用 Strut 的 FreeMarker 设置。当然,在那时,当他们这样做时,这可能是最合理的解决方法,但它不再是一段时间了,尤其是从 2.3.22 开始。
旧答案(过时):
您从模板中查看 Java 对象的方式取决于所ObjectWrapper
使用的,这是一个 FreeMarker 配置设置。根据您的示例,Struts 使用 aBeansWrapper
及其默认设置,而 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)
. 有了这个,Map
-s 的方法是不可见的,就像 with 一样DefaultObjectWrapper
,所以你可以安全myMap.foo
地使用myMap[key]
。但是,如果您很少需要使用非字符串键获取某些内容,则可以使用myMap(nonStringKey)
(是的,使用()
而不是[]
)。最后一个不适用于DefaultObjectWrapper
. (希望 FreeMarker 2.4 能解决这个乱七八糟的非字符串键问题,但它不会很快出现......)
那么接下来的问题是如何用Spring设置对象包装器。我不在家。据我所知,您有一个具有属性的FreeMarkerConfigurer
bean,该属性是最终传递给基于 FreeMarker 的配置 API 的对象。因此,您应该能够添加一个引用要使用的类名的属性(或者它可能只是像 Struts 那样使用默认实例)。问题是,基于属性的 API 相当有限,因此您不能同时创建和配置(调用) a 。您当然可以在 spring 配置文件中执行此操作,但我看不到将其注入 的方法,除非您创建整个freemarkerSettings
Properties
Properties
object_wrapper
ObjectWrapper
beans
BeansWrapper
setSimpleMapWrapper
BeansWrapper
FreeMarkerConfigurer
freemarker.template.Configuration
对象作为 bean,并将其注入到它FreeMarkerConfigurer
的configuration
属性中。因此,也许最简单的解决方法是扩展BeansWrapper
以覆盖 的默认值simpleMapWrapper
,然后通过object_wrapper
. (以防有人稍后阅读,FreeMarker 2.3.21 可能会扩展属性配置 API,以便您可以设置object_wrapper
为BeansWrapper() { simpleMapWrapper = true }
。)