Freemarker: comment parcourir la carte en utilisant des énumérations comme clés

Le code suivant ne fonctionne pas car Freemarker semble transtyper la valeur de l’expression inside [] en Ssortingng, puis l’utiliser comme clé, ce qui n’est pas ce à quoi on s’attendait.

Préparation d’un modèle de modèle:

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

my.ftl:

   
  • ${key} = ${value}
  • Dans la documentation Freemarker, il est décrit comment accéder à Enum lui-même, mais je n’ai rien trouvé sur la façon d’obtenir une valeur d’un hachage en utilisant Enum comme clé.

    Je vous remercie.

    Pour paraphraser la FAQ de la documentation Freemarker à ce sujet,

    Vous ne pouvez pas utiliser de clés autres que des chaînes dans l’expression myMap [key]. Vous pouvez utiliser des méthodes!

    Vous pouvez donc créer un haricot qui vous permet d’accéder à votre Java EnumMap (ie). Ensuite, instanciez simplement ce haricot avec votre mapp et placez-le dans votre modèle.

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

    Je suis un peu confus quant à l’objective général que vous essayez d’atteindre. Si vous avez juste besoin de lister les valeurs de l’énum (ou peut-être une valeur d’affichage pour chacune). Il y a un moyen beaucoup plus facile de le faire.

    Une façon dont j’ai vu ce problème résolu consiste à append une valeur d’affichage aux instances Enum.

    c’est à dire

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

    Cela vous permet de mettre l’énum lui-même dans votre configuration et d’effectuer une itération sur toutes les instances.

     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); 

    Ensuite, vous pouvez parcourir l’énumération,

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

    La réponse acceptée n’est pas la solution la plus simple depuis 2.3.22. Bien que myMap[key] assume toujours une clé de chaîne ( voir l’entrée de FAQ dans la section Pourquoi ), vous pouvez désormais utiliser myMap?api.get(key) comme solution de contournement. Il a besoin de configuration cependant:

    • Tout d’abord api_builtin_enabled est interdit par défaut. Vous devez donc définir le api_builtin_enabled ( Configuration.setAPIBuiltinEnabled(boolean) ) sur true .
    • Ensuite, l’ object_wrapper ( Configuration.setObjectWrapper(ObjectWrapper) ) utilisé doit prendre en charge cette fonctionnalité (exposition de l’API). Si vous ne définissez pas object_wrapper où que object_wrapper soit, le simple fait d’augmenter le paramètre incompatible_improvements (paramètre de constructeur de Configuration.setIncompatibleImprovements(Version) ou Configuration.setIncompatibleImprovements(Version) ) à 2.3.22 résout ce problème. Si vous définissez object_wrapper (c’est-à-dire que vous écrasez la valeur par défaut) et qu’il s’agit d’une occurrence de DefaultObjectWrapper , notez que DefaultObjectWrapper possède sa propre propriété incompatibleImprovements qui doit être définie sur 2.3.22. Si vous utilisez BeansWrapper pur (non recommandé!), Vous ne devez rien faire car il prend toujours en charge cette fonctionnalité.