Freemarker, der über Hashmap-Schlüssel iteriert

Freemarker hat zwei Auflistungsdatentypen, Listen und Hashmaps. Gibt es eine Möglichkeit, über Hashmap-Schlüssel zu iterieren, genau wie mit Listen?

Also, wenn ich eine Var mit Daten habe, sagen wir mal:

user : { name : "user" email : "looser@everything.com" homepage : "http://nosuchpage.org" } 

Ich möchte alle Eigenschaften des Benutzers mit ihrem Wert drucken. Das ist ungültig, aber das Ziel ist klar:

  ${prop} = ${user.get(prop)}  

Edit: Verwenden Sie diese Lösung nicht mit FreeMarker 2.3.25 und höher, besonders nicht mit .get(prop) . Siehe andere Antworten.

Sie verwenden die eingebaute Tastenfunktion , zB sollte dies funktionieren:

 < #list user?keys as prop> ${prop} = ${user.get(prop)}  

Zu Ihrer Information: Die Syntax zum Abrufen der Werte sieht folgendermaßen aus:

http://freemarker.sourceforge.net/docs/ref_builtins_hash.html

 < #assign h = {"name":"mouse", "price":50}> < #assign keys = h?keys> < #list keys as key>${key} = ${h[key]};  

Seit 2.3.25, mach es so:

 < #list user as propName, propValue> ${propName} = ${propValue}  

Beachten Sie, dass dies auch mit Nicht-String-Schlüsseln funktioniert (im Gegensatz zu map[key] , die dann als map?api.get(key) ).

Vor 2.3.25 war die Standardlösung:

 < #list user?keys as prop> ${prop} = ${user[prop]}  

Einige wirklich alte FreeMarker-Integrationen verwenden jedoch eine seltsame Konfiguration, bei der die öffentlichen Map Methoden (wie getClass ) als Schlüssel erscheinen. BeansWrapper geschieht, da sie einen reinen BeansWrapper (anstelle von DefaultObjectWrapper ) verwenden, dessen Eigenschaft simpleMapWrapper auf false simpleMapWrapper wurde. Sie sollten solch ein Setup vermeiden, da es die Methoden mit realen Map Einträgen mischt. Wenn Sie jedoch in solch ein unglückliches Setup geraten, besteht die Möglichkeit, die exponierten Java-Methoden wie user.entrySet() , user.get(key) usw. zu user.get(key) , und nicht die Template-Sprachkonstrukte wie ?keys oder user[key] .

Wenn Sie einen BeansWrapper mit einem Exposure-Level von Expose.SAFE oder Expose.ALL verwenden, kann der Java-Standardansatz des Iterierens des Entry-Sets verwendet werden:

Zum Beispiel funktioniert das Folgende in Freemarker (seit mindestens Version 2.3.19):

 < #list map.entrySet() as entry>   

In Struts2 wird zum Beispiel eine Erweiterung des BeanWrappers verwendet, wobei die Belichtungsstufe als Standard für diese Art der Iteration verwendet wird.

Iterieren von Objekten

Wenn Ihre Map-Schlüssel ein Objekt und keine Zeichenfolge sind, können Sie sie mit Freemarker iterieren.

1) Konvertiere die Karte in eine Liste im Controller:

 List> convertedMap = new ArrayList(originalMap.entrySet()); 

2) Iteriere die Karte in der Freemarker-Vorlage, indem du auf das Objekt im Schlüssel und das Objekt im Wert zugreifst:

 < #list convertedMap as item> < #assign myObjectKey = item.getKey()/> < #assign myObjectValue = item.getValue()/> [...]  

Sie können ein einfaches Anführungszeichen verwenden, um auf den Schlüssel zuzugreifen, den Sie in Ihrem Java-Programm festgelegt haben.

Wenn Sie eine Map in Java so einstellen

 Map hash = new HashMap(); hash.put("firstname", "a"); hash.put("lastname", "b"); Map map = new HashMap(); map.put("hash", hash); 

Dann kannst du die Mitglieder von ‘hash’ in Freemarker so erreichen –

 ${hash['firstname']} ${hash['lastname']} 

Ausgabe :

 a b 

Der Vollständigkeit halber sei erwähnt, dass es in Freemarker seit kurzem einen ordentlichen Umgang mit leeren Sammlungen gibt.

Die einfachste Möglichkeit, eine Map zu iterieren, ist:

 < #list tags> 
    < #items as tagName, tagCount>
  • {$tagName} (${tagCount})
< #else>

No tags found.

Nicht mehr < #if ...> Wrapper.