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 ...>фантики.