Freemarker итерации по ключам hashmap
Freemarker имеет два типа данных коллекции, списки и хэш-карты Есть ли способ перебирать ключи hashmap так же, как мы делаем со списками?
поэтому, если у меня есть var с данными, скажем:
user : {
name : "user"
email : "looser@everything.com"
homepage : "http://nosuchpage.org"
}
Я хотел бы распечатать все свойства пользователя с их значением. Это неверно, но цель ясна:
<#list user.props() as prop>
${prop} = ${user.get(prop)}
</#list>
7 ответов:
Edit: Не используйте это решение с FreeMarker 2.3.25 и выше, особенно не
.get(prop)
. См. другие ответы.вы используете встроенный ключи, например, это должно работать:
<#list user?keys as prop> ${prop} = ${user.get(prop)} </#list>
FYI, похоже, что синтаксис для извлечения значений изменился в соответствии с:
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>
начиная с 2.3.25, сделайте это так:
<#list user as propName, propValue> ${propName} = ${propValue} </#list>
обратите внимание, что это также работает с нестроковыми ключами (в отличие от
map[key]
, который должен был быть написан какmap?api.get(key)
потом).до 2.3.25 стандартным решением было:
<#list user?keys as prop> ${prop} = ${user[prop]} </#list>
однако некоторые действительно старые интеграции FreeMarker используют странную конфигурацию, где публика
Map
методы (например,getClass
) появляются как ключи. Это происходит, как они используют чистыйBeansWrapper
(вместоDefaultObjectWrapper
), чьиsimpleMapWrapper
имущество было оставлено наfalse
. Вам следует избегать такой настройки, так как она смешивает методы с реальнымиMap
записи. Но если вы столкнетесь с такой неудачной установкой, способ избежать ситуации-использовать открытые методы Java, такие какuser.entrySet()
,user.get(key)
и т. д., и не используя языковые конструкции шаблона, такие как?keys
илиuser[key]
.
при использовании BeansWrapper С уровнем экспозиции Expose.Безопасно или разоблачить.Все, тогда можно использовать стандартный подход Java к итерации набора записей:
например, в Freemarker будет работать следующее (Начиная как минимум с версии 2.3.19):
<#list map.entrySet() as entry> <input type="hidden" name="${entry.key}" value="${entry.value}" /> </#list>
в Struts2, например, расширение BeanWrapper используется с уровнем экспозиции по умолчанию, чтобы разрешить этот способ итерации.
Переборе Объектов
если ваши ключи карты-это объект, а не строка, вы можете повторить его с помощью Freemarker.
1) преобразовать карту в список в контроллере:
List<Map.Entry<myObjectKey, myObjectValue>> convertedMap = new ArrayList(originalMap.entrySet());
2) Повторите карту в шаблоне Freemarker, получая доступ к объекту в ключе и объекту в значении:
<#list convertedMap as item> <#assign myObjectKey = item.getKey()/> <#assign myObjectValue = item.getValue()/> [...] </#list>
вы можете использовать одну кавычку для доступа к ключу, который вы установили в вашей программе Java.
Если вы установите карту в Java, как это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);
тогда вы можете получить доступ к членам "хэш" в Freemarker, как это -
${hash['firstname']} ${hash['lastname']}
выход :
a b
для полноты картины стоит отметить, что с недавнего времени в Freemarker есть приличная обработка пустых коллекций.
таким образом, наиболее удобный способ итерации карты:
<#list tags> <ul class="posts"> <#items as tagName, tagCount> <li>{$tagName} (${tagCount})</li> </#items> </ul> <#else> <p>No tags found.</p> </#list>
не больше
<#if ...>
фантики.