¿Cómo recorrer un HashMap en JSP?


146

¿Cómo puedo recorrer un HashMapen JSP?

<%
    HashMap<String, String> countries = MainUtils.getCountries(l);
%>

<select name="country">
    <% 
        // Here I need to loop through countries.
    %>
</select>

17
Por cierto, a HashMapes desordenado por naturaleza. ¿Está seguro de que no necesita TreeMap(clasificación automática por clave) o LinkedHashMap(mantiene el orden de inserción)?
BalusC

Respuestas:


308

De la misma manera que lo haría en un código Java normal.

for (Map.Entry<String, String> entry : countries.entrySet()) {
    String key = entry.getKey();
    String value = entry.getValue();
    // ...
}

Sin embargo , los scriptlets (código Java sin procesar en archivos JSP, esas <% %>cosas) se consideran una mala práctica . Recomiendo instalar JSTL (simplemente suelte el archivo JAR /WEB-INF/liby declare los taglibs necesarios en la parte superior de JSP). Tiene una <c:forEach>etiqueta que puede iterar entre otras Map. Cada iteración le dará un Map.Entryrespaldo que a su vez tiene getKey()y getValue()métodos.

Aquí hay un ejemplo básico:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<c:forEach items="${map}" var="entry">
    Key = ${entry.key}, value = ${entry.value}<br>
</c:forEach>

Por lo tanto, su problema particular se puede resolver de la siguiente manera:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<select name="country">
    <c:forEach items="${countries}" var="country">
        <option value="${country.key}">${country.value}</option>
    </c:forEach>
</select>

Necesita a Servleto a ServletContextListenerpara colocar el ${countries}en el alcance deseado. Si se supone que esta lista está basada en una solicitud, utilice el Servlet's doGet():

protected void doGet(HttpServletRequest request, HttpServletResponse response) {
    Map<String, String> countries = MainUtils.getCountries();
    request.setAttribute("countries", countries);
    request.getRequestDispatcher("/WEB-INF/page.jsp").forward(request, response);
}

O si se supone que esta lista es una constante de toda la aplicación, use ServletContextListener's' contextInitialized()para que se cargue solo una vez y se guarde en la memoria:

public void contextInitialized(ServletContextEvent event) {
    Map<String, String> countries = MainUtils.getCountries();
    event.getServletContext().setAttribute("countries", countries);
}

En ambos casos countries, estará disponible en EL por ${countries}.

Espero que esto ayude.

Ver también:


2
@Khue: sí, también puedes poner atributos en la sesión. Solo que no entiendo por qué le gustaría duplicar los datos de toda la aplicación en varias sesiones.
BalusC

Creo que en caso de información basada en la sesión. Gracias por la muy buena explicación.
Khue Vu

Estoy seguro de que la respuesta es obvia, pero, ¿por qué los scriptlets se consideran una mala práctica? En ausencia de JSTL debido al mantenimiento de una aplicación heredada, esta es mi única opción.
Zibbobz

@Zibbobz: el texto "mala práctica" es un enlace. Haz click en eso.
BalusC

1

Dependiendo de lo que desee lograr dentro del ciclo, repita uno de estos en su lugar:

  • countries.keySet()
  • countries.entrySet()
  • countries.values()

sí, con esto obtengo un conjunto de claves, pero ¿cómo puedo integrarlo en un campo de selección para html?
blub

66
esto no responde a la pregunta que es específica sobre JSP
Taoufik Mohdit

0

El siguiente código me funciona

Primero definí el partnerTypesMapsiguiente como en el lado del servidor,

Map<String, String> partnerTypes = new HashMap<>();

después de agregarle valores, agregué el objeto a model,

model.addAttribute("partnerTypesMap", partnerTypes);

Cuando renderizo la página que uso a continuación foreachpara imprimirlas una por una.

<c:forEach items="${partnerTypesMap}" var="partnerTypesMap">
      <form:option value="${partnerTypesMap['value']}">${partnerTypesMap['key']}</form:option>
</c:forEach>
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.