FreeMarker iteruje nad kluczami hashmap

Freemarker ma dwa typy danych kolekcji, listy i hashmapy Czy istnieje sposób na iterację kluczy hashmapowych, tak jak robimy to z listami?

Więc jeśli mam var z danymi powiedzmy:

user : {
  name : "user"
  email : "[email protected]"
  homepage : "http://nosuchpage.org"
}

Chciałbym wydrukować wszystkie właściwości użytkownika z ich wartością. Jest to niepoprawne, ale cel jest jasny:

<#list user.props() as prop>
  ${prop} = ${user.get(prop)}
</#list>
Author: Lipis, 2009-09-30

7 answers

Edit: nie używaj tego rozwiązania z Freemarkerem 2.3.25 i nowszymi, szczególnie nie .get(prop). Zobacz inne odpowiedzi.

Używasz wbudowanych klawiszy , np. powinno działać:

<#list user?keys as prop>
    ${prop} = ${user.get(prop)}
</#list>  
 94
Author: skaffman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-26 10:01:04

Dla twojej wiadomości, wygląda na to, że składnia pobierania wartości została zmieniona zgodnie z:

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]}; </#list>
 48
Author: Nick Spacek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-30 17:24:00

Od 2.3.25, zrób to tak:

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

Zauważ, że działa to również z klawiszami nietekstowymi(w przeciwieństwie do map[key], które musiały być zapisane jako map?api.get(key)).

Przed 2.3.25 rozwiązaniem standardowym było:

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

Jednak niektóre naprawdę stare integracje FreeMarker używają dziwnej konfiguracji, gdzie publiczne metody Map (Jak getClass) pojawiają się jako klucze. Dzieje się tak, ponieważ używają czystego BeansWrapper (zamiast DefaultObjectWrapper), którego właściwość simpleMapWrapper została pozostawiona na false. Należy unikać takich konfiguracja, ponieważ miesza metody z prawdziwymi wpisami Map. Ale jeśli natkniesz się na tak niefortunną konfigurację, sposobem na ucieczkę z sytuacji jest użycie odkrytych metod Javy, takich jakuser.entrySet(), user.get(key), itd., a nie używać szablonowych konstrukcji językowych jak ?keys czy user[key].

 25
Author: ddekany,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-20 21:32:34

Jeśli używasz BeansWrapper o poziomie ekspozycji.Bezpieczne lub narażone.Wszystkie, wtedy można zastosować standardowe podejście Javy do iteracji zbioru wejściowego:

Na przykład w Freemarkerze (od co najmniej wersji 2.3.19) będą działać:

<#list map.entrySet() as entry>  
  <input type="hidden" name="${entry.key}" value="${entry.value}" />
</#list>

W Struts2, na przykład, rozszerzenie BeanWrapper jest używane z domyślnym poziomem ekspozycji, aby umożliwić ten sposób iteracji.

 12
Author: rees,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-06 03:14:34

Iteracja Obiektów

Jeśli Twoje klucze mapy są obiektem, a nie łańcuchem znaków, możesz je iterować za pomocą Freemarkera.

1) Konwertuj mapę na Listę w kontrolerze:

List<Map.Entry<myObjectKey, myObjectValue>> convertedMap  = new ArrayList(originalMap.entrySet());

2) iteracja mapy w szablonie Freemarker, dostęp do obiektu w kluczu i obiektu w wartości:

<#list convertedMap as item>
    <#assign myObjectKey = item.getKey()/>
    <#assign myObjectValue = item.getValue()/>
    [...]
</#list>
 2
Author: Tk421,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-20 08:42:08

Możesz użyć jednego cytatu, aby uzyskać dostęp do klucza ustawionego w programie Java.

Jeśli ustawisz mapę w Javie w ten sposób

Map<String,Object> hash = new HashMap<String,Object>();
hash.put("firstname", "a");
hash.put("lastname", "b");

Map<String,Object> map = new HashMap<String,Object>();
map.put("hash", hash);

Następnie możesz uzyskać dostęp do członków 'hash' w Freemarkerze w następujący sposób-

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

Wyjście:

a
b
 1
Author: Ashish Chhabria,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-19 18:28:55

Dla kompletności, warto wspomnieć, że od niedawna we Freemarkerze istnieje przyzwoita obsługa pustych zbiorów.

Więc najwygodniejszym sposobem iteracji mapy jest:

<#list tags>
<ul class="posts">
    <#items as tagName, tagCount>
        <li>{$tagName} (${tagCount})</li>
    </#items>
</ul>
<#else>
    <p>No tags found.</p>
</#list>
Koniec z opakowaniami.
 0
Author: Ondra Žižka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-23 16:09:56