Wie durchlaufe ich eine HashMap in JSP?

146

Wie kann ich eine HashMapin JSP durchlaufen ?

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

<select name="country">
    <% 
        // Here I need to loop through countries.
    %>
</select>
blub
quelle
17
A HashMapist übrigens von Natur aus ungeordnet. Sind Sie sicher, dass Sie dies nicht benötigen TreeMap(automatische Sortierung nach Schlüssel) oder LinkedHashMap(Beibehaltungsreihenfolge beibehalten)?
BalusC

Antworten:

308

Genau wie bei normalem Java-Code.

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

Allerdings , Scriptlets (raw Java - Code in JSP - Dateien, diese <% %>Dinge) ist eine als schlechte Praxis . Ich empfehle, JSTL zu installieren (legen Sie einfach die JAR-Datei ab /WEB-INF/libund deklarieren Sie die erforderlichen Taglibs über JSP). Es hat ein <c:forEach>Tag, das unter anderem über iterieren kann Map. Jede Iteration wird Ihnen eine Map.EntryRückseite , die wiederum hat getKey()und getValue()Methoden.

Hier ist ein einfaches Beispiel:

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

Somit kann Ihr spezielles Problem wie folgt gelöst werden:

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

Sie benötigen ein Servletoder ein ServletContextListener, um das ${countries}in den gewünschten Bereich zu platzieren. Wenn diese Liste anforderungsbasiert sein soll, verwenden Sie ServletFolgendes 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);
}

Oder wenn diese Liste eine anwendungsweite Konstante sein soll, verwenden Sie ServletContextListener's, contextInitialized()damit sie nur einmal geladen und gespeichert wird:

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

In beiden Fällen countrieswird der in EL von verfügbar sein ${countries}.

Hoffe das hilft.

Siehe auch:

BalusC
quelle
2
@ Khue: Ja, Sie können auch Attribute in die Sitzung einfügen. Ich verstehe nur nicht, warum Sie anwendungsweite Daten über mehrere Sitzungen hinweg duplizieren möchten.
BalusC
Ich denke im Fall von sitzungsbasierten Informationen. Danke für die sehr nette Erklärung.
Khue Vu
Ich bin mir sicher, dass die Antwort offensichtlich ist, aber - warum werden Scriptlets als schlechte Praxis angesehen? In Abwesenheit von JSTL aufgrund der Wartung einer Legacy-Anwendung ist dies meine einzige Option.
Zibbobz
@Zibbobz: Der Text "schlechte Praxis" ist ein Link. Klick es an.
BalusC
1

Je nachdem, was Sie in der Schleife erreichen möchten, durchlaufen Sie stattdessen eine der folgenden Optionen:

  • countries.keySet()
  • countries.entrySet()
  • countries.values()
Jim Garrison
quelle
Ja, damit bekomme ich alle Schlüsselsätze, aber wie kann ich sie in ein Auswahlfeld für HTML integrieren?
Blub
6
Dies beantwortet nicht die Frage, die spezifisch für JSP ist
Taoufik Mohdit
0

Der folgende Code funktioniert für mich

Zuerst habe ich das partnerTypesMapGleiche unten auf der Serverseite definiert.

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

Nachdem ich Werte hinzugefügt hatte, fügte ich das Objekt hinzu model.

model.addAttribute("partnerTypesMap", partnerTypes);

Beim Rendern der Seite verwende ich unten foreach, um sie einzeln zu drucken.

<c:forEach items="${partnerTypesMap}" var="partnerTypesMap">
      <form:option value="${partnerTypesMap['value']}">${partnerTypesMap['key']}</form:option>
</c:forEach>
tk_
quelle