Comment parcourir un HashMap dans JSP?


146

Comment puis-je parcourir une HashMapJSP en boucle ?

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

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

17
À propos, un HashMapest par nature non ordonné. Êtes-vous certain de ne pas avoir besoin de TreeMap(tri automatique par clé) ou LinkedHashMap(maintien de l'ordre d'insertion)?
BalusC

Réponses:


308

De la même manière que vous le feriez avec du code Java normal.

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

Cependant , les scriptlets (code Java brut dans les fichiers JSP, ces <% %>choses) sont considérés comme une mauvaise pratique . Je recommande d'installer JSTL (déposez simplement le fichier JAR /WEB-INF/libet déclarez les taglibs nécessaires en haut de JSP). Il a une <c:forEach>balise qui peut parcourir entre autres Maps. Chaque itération vous donnera un Map.Entryretour qui à son tour a getKey()et des getValue()méthodes.

Voici un exemple de base:

<%@ 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>

Ainsi, votre problème particulier peut être résolu comme suit:

<%@ 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>

Vous avez besoin d'un Servletou d'un ServletContextListenerpour placer le ${countries}dans la portée souhaitée. Si cette liste est censée être basée sur des requêtes, utilisez les 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);
}

Ou si cette liste est supposée être une constante à l'échelle de l'application, utilisez ServletContextListenerles contextInitialized()pour qu'elle ne soit chargée qu'une seule fois et conservée en mémoire:

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

Dans les deux cas, le countriessera disponible en EL par ${countries}.

J'espère que cela t'aides.

Voir également:


2
@Khue: oui, vous pouvez également mettre des attributs dans la session. Je ne vois pas pourquoi vous souhaiteriez dupliquer des données à l'échelle de l'application sur plusieurs sessions.
BalusC

Je pense en cas d'informations basées sur la session. Merci pour la très belle explication.
Khue Vu

Je suis sûr que la réponse est évidente mais - pourquoi les scriptlets sont-ils considérés comme une mauvaise pratique? En l'absence de JSTL en raison du maintien d'une application héritée, c'est ma seule option.
Zibbobz

@Zibbobz: le texte "mauvaise pratique" est un lien. Clique dessus.
BalusC

1

En fonction de ce que vous souhaitez accomplir dans la boucle, parcourez plutôt l'un de ces éléments:

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

oui, avec cela, j'obtiens un jeu de clés, mais comment puis-je l'intégrer dans un champ de sélection pour HTML?
blub

6
cela ne répond pas à la question spécifique à propos de JSP
Taoufik Mohdit

0

Le code ci-dessous fonctionne pour moi

J'ai d'abord défini la même partnerTypesMapchose ci-dessous côté serveur,

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

après avoir ajouté des valeurs, j'ai ajouté l'objet à model,

model.addAttribute("partnerTypesMap", partnerTypes);

Lors du rendu de la page, j'utilise ci-dessous foreachpour les imprimer une par une.

<c:forEach items="${partnerTypesMap}" var="partnerTypesMap">
      <form:option value="${partnerTypesMap['value']}">${partnerTypesMap['key']}</form:option>
</c:forEach>
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.