Freemarker:如何使用枚举作为键来迭代Map

以下代码不起作用,因为Freemarker似乎将[]中的表达式的值转换为String,然后将其用作键,这不是实际预期的。

准备模板模型:

Map myMap; myMap.put(MyEnum.FOO, "Foo"); myMap.put(MyEnum.BAR, "Bar"); templateModel.put("myMap", myMap); 

my.ftl:

   
  • ${key} = ${value}
  • 在Freemarker文档中,它描述了如何访问Enum本身,但我没有找到任何关于如何使用Enum作为键从哈希值中获取值。

    谢谢。

    要解释Freemarker文档常见问题解答 ,

    您不能在myMap [key]表达式中使用非字符串键。 你可以使用方法!

    因此,您可以创建一个bean,为您提供访问Java EnumMap的方法(即)。 然后用你的mapp实例化这个bean,并将bean放在你的Model中。

     class EnumMap { HashMap map = new HashMap(); public String getValue(MyEnum e) { return map.get(e); } ..constructor, generics, getters, setters left out. } 

    我对你想要达到的目标有点困惑。 如果您只需要列出枚举值(或者每个值的显示值)。 有一种更容易的方法来做到这一点。

    我看到这个问题解决的一种方法是在Enum实例上放置一个显示值。

     enum MyEnum { FOO("Foo"), BAR_EXAMPLE("Bar Example"); private String displayValue; MyEnum(String displayValue) { this.displayValue = displayValue; } public String getDisplay() { return displayValue; } } 

    这允许您将Enum本身放入您的配置中,并迭代所有实例。

     SimpleHash globalModel = new SimpleHash(); TemplateHashModel enumModels = BeansWrapper.getDefaultInstance().getEnumModels(); TemplateHashModel myEnumModel = (TemplateHashModel) enumModels.get("your.fully.qualified.enum.MyEnum"); globalModel.put("MyEnum", myEnumModel); freemarkerConfiguration.setAllSharedVariables(globalModel); 

    然后你可以遍历枚举,

     <#list MyEnum?values as item> ${item.display}  

    接受的答案不是自2.3.22以来最简单的解决方案。 虽然myMap[key]仍假定一个字符串键( 请参阅常见问题解答条目原因 ),现在可以使用myMap?api.get(key)作为解决方法。 它需要一些配置:

    • 首先,默认情况下不允许使用?api ,因此您需要将api_builtin_enabledConfiguration.setAPIBuiltinEnabled(boolean) )设置为true
    • 然后,使用的object_wrapperConfiguration.setObjectWrapper(ObjectWrapper) )需要支持此function(公开API)。 如果没有在任何地方设置object_wrapper ,那么只需将incompatible_improvements设置( Configuration构造函数参数或Configuration.setIncompatibleImprovements(Version) )增加到2.3.22即可解决此问题。 如果设置object_wrapper (即,覆盖默认值),并且它是DefaultObjectWrapper实例,请注意DefaultObjectWrapper具有自己的incompatibleImprovements属性,该属性必须设置为2.3.22。 如果您使用纯BeansWrapper (不推荐!),那么您必须不做任何事情,因为它始终支持此function。