Freemarker iterando sobre claves hashmap

Freemarker tiene dos tipos de datos de recostackción, listas y hashpeps ¿Hay alguna manera de iterar sobre las claves de hashmap tal como lo hacemos con las listas?

Entonces, si tengo una var con datos, digamos:

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

Me gustaría imprimir todas las propiedades del usuario con su valor. Esto no es válido, pero el objective es claro:

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

Editar: No use esta solución con FreeMarker 2.3.25 y superior, especialmente no .get(prop) . Ver otras respuestas

Utiliza la función de teclas integradas, por ejemplo, esto debería funcionar:

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

FYI, parece que la syntax para recuperar los valores ha cambiado de acuerdo con:

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]};  

Desde 2.3.25, hazlo así:

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

Tenga en cuenta que esto también funciona con teclas que no son de cadena (a diferencia de map[key] , que se tenía que escribir como map?api.get(key) luego).

Antes de 2.3.25, la solución estándar era:

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

Sin embargo, algunas integraciones de FreeMarker realmente antiguas usan una configuración extraña, donde los métodos públicos de Map (como getClass ) aparecen como claves. Eso sucede porque usan un BeansWrapper puro (en lugar de DefaultObjectWrapper ) cuya propiedad simpleMapWrapper se dejó en false . Debe evitar dicha configuración, ya que mezcla los métodos con las entradas de Map reales. Pero si se encuentra con una configuración tan desafortunada, la forma de escapar de la situación es usar los métodos expuestos de Java, como user.entrySet() , user.get(key) , etc., y no usar las construcciones de lenguaje de plantilla como ?keys o user[key] .

Si usa BeansWrapper con un nivel de exposición de Expose.SAFE o Expose.ALL, se puede utilizar el enfoque estándar de Java para iterar el conjunto de entrada:

Por ejemplo, lo siguiente funcionará en Freemarker (desde al menos la versión 2.3.19):

 < #list map.entrySet() as entry>   

En Struts2, por ejemplo, se usa una extensión de BeanWrapper con el nivel de exposición predeterminado para permitir esta forma de iteración.

Iterar objetos

Si las claves de su mapa son un objeto y no una cadena, puede iterar utilizando Freemarker.

1) Convierta el mapa en una lista en el controlador:

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

2) Iterar el mapa en la plantilla de Freemarker, acceder al objeto en la clave y el objeto en el valor:

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

Puede usar una comilla simple para acceder a la clave que estableció en su progtwig Java.

Si configura un mapa en Java como este

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

Entonces puedes acceder a los miembros de ‘hash’ en Freemarker de esta manera:

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

Salida:

 a b 

Para completar, vale la pena mencionar que hay un manejo decente de colecciones vacías en Freemarker desde hace poco.

Entonces la forma más conveniente de iterar un mapa es:

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

No tags found.

No más < #if ...>