Java Freemarker:如何使用枚举作为键在地图中迭代

Java Freemarker:如何使用枚举作为键在地图中迭代,java,enums,map,key,freemarker,Java,Enums,Map,Key,Freemarker,以下代码不起作用,因为Freemarker似乎将[]内表达式的值强制转换为字符串,然后将其用作键,而这并不是实际期望的结果 准备模板模型: Map<MyEnum, Object> myMap; myMap.put(MyEnum.FOO, "Foo"); myMap.put(MyEnum.BAR, "Bar"); templateModel.put("myMap", myMap); Map-myMap; myMap.put(MyEnum.FOO,“FOO”); myMap.put(M

以下代码不起作用,因为Freemarker似乎将[]内表达式的值强制转换为字符串,然后将其用作键,而这并不是实际期望的结果

准备模板模型:

Map<MyEnum, Object> myMap;
myMap.put(MyEnum.FOO, "Foo");
myMap.put(MyEnum.BAR, "Bar");
templateModel.put("myMap", myMap);
Map-myMap;
myMap.put(MyEnum.FOO,“FOO”);
myMap.put(MyEnum.BAR,“BAR”);
templateModel.put(“myMap”,myMap);
my.ftl:

<#list myMap?keys as key>
    <#assign value = myMap[key]>
    <li>${key} = ${value}</li>
</#list>

  • ${key}=${value}
  • 在中,它描述了如何访问枚举本身,但我没有找到任何关于如何使用枚举作为键从散列中获取值的内容

    谢谢。

    要解释一下

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

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

    class EnumMap
    {
        HashMap<MyEnum, String> map = new HashMap<MyEnum, String>();
    
        public String getValue(MyEnum e)
        {
            return map.get(e);
        }    
        ..constructor, generics, getters, setters left out.
    }
    
    这允许您将枚举本身放入配置中,并迭代所有实例

    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}
    </#list> 
    
    
    ${item.display}
    
    自2.3.22以来,公认的答案并不是最简单的解决方案。虽然
    myMap[key]
    仍然采用字符串键(),但现在可以使用
    myMap?api.get(key)
    作为解决方法。但它需要一些配置:

    • 首先,默认情况下不允许使用
      ?api
      ,因此需要将
      api内置启用设置设置为
      true
      Configuration.setapibultinenabled(boolean)
    • 然后,使用的
      对象包装器
      配置.setObjectWrapper(ObjectWrapper)
      )需要支持此功能(公开API)。如果您没有在任何地方设置
      对象\u包装
      ,则只需将
      不兼容的\u改进
      设置(
      配置
      构造函数参数,或
      配置。setcompatiblemprovisions(Version)
      )增加到2.3.22即可解决此问题。如果设置了
      object\u wrapper
      (即覆盖默认值),并且它是
      DefaultObjectWrapper
      实例,那么请注意
      DefaultObjectWrapper
      有自己的
      不兼容改进
      属性,必须设置为2.3.22。如果您使用的是纯
      BeansWrapper
      (不推荐!),则无需执行任何操作,因为它始终支持此功能

    但是,当我想使用enum作为键访问地图时,它不起作用。mymap[MyEnum.SOMETHING]不起作用是有道理的,但我也不能使用mymap.get(MyEnum.SOMETHING)!请注意,这不再是最简单的解决方案。请看我的答案。@Wouter Lievens:
    mymap.get()
    仅适用于特定的
    object\u wrapper
    设置值(纯
    BeansWrapper
    with
    simpleMaps=false
    ),但强烈反对使用该值,而且在现有应用程序下彻底更改
    object\u wrapper
    ,很容易破坏它。无论如何,请参阅我的答案,以获得更“可移植”的解决方案。
    <#list MyEnum?values as item>
        ${item.display}
    </#list>