Bagaimana cara mengulang melalui HashMap di JSP?

146

Bagaimana saya bisa mengulang melalui HashMapJSP?

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

<select name="country">
    <% 
        // Here I need to loop through countries.
    %>
</select>
blub
sumber
17
Omong-omong, a HashMapsecara alami tidak teratur. Apakah Anda yakin tidak perlu TreeMap(mengurutkan menurut kunci) atau LinkedHashMap(mempertahankan urutan penyisipan)?
BalusC

Jawaban:

308

Sama seperti yang Anda lakukan pada kode Java normal.

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

Namun , scriptlets (kode Java mentah dalam file JSP, <% %>hal - hal itu) dianggap praktik yang buruk . Saya sarankan untuk menginstal JSTL (cukup masukkan file JAR /WEB-INF/libdan nyatakan taglibs yang diperlukan di atas JSP). Ini memiliki <c:forEach>tag yang dapat beralih di antara yang lain Map. Setiap iterasi akan memberi Anda Map.Entrypunggung yang pada gilirannya memiliki getKey()dan getValue()metode.

Inilah contoh dasar:

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

Dengan demikian masalah khusus Anda dapat diselesaikan sebagai berikut:

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

Anda perlu a Servletatau a ServletContextListeneruntuk menempatkannya ${countries}dalam ruang lingkup yang diinginkan. Jika daftar ini seharusnya berdasarkan permintaan, maka gunakan 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);
}

Atau jika daftar ini seharusnya menjadi konstan aplikasi-lebar, kemudian menggunakan ServletContextListener's contextInitialized()sehingga akan dimuat hanya sekali dan disimpan dalam memori:

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

Dalam kedua kasus itu countriesakan tersedia di EL oleh ${countries}.

Semoga ini membantu.

Lihat juga:

BalusC
sumber
2
@ Khue: ya, Anda juga bisa menaruh atribut di sesi ini. Saya hanya tidak melihat mengapa Anda ingin menduplikasi data lebar aplikasi selama beberapa sesi.
BalusC
Saya pikir dalam kasus info berbasis sesi. Terima kasih atas penjelasannya.
Khue Vu
Saya yakin jawabannya jelas tetapi - mengapa scriptlets dianggap praktik yang buruk? Dengan tidak adanya JSTL karena mempertahankan aplikasi warisan, ini adalah satu-satunya pilihan saya.
Zibbobz
@Zibbobz: teks "praktik buruk" adalah tautan. Klik itu.
BalusC
1

Bergantung pada apa yang ingin Anda capai dalam loop, beralihlah ke salah satu dari ini:

  • countries.keySet()
  • countries.entrySet()
  • countries.values()
Jim Garrison
sumber
ya, dengan ini saya mendapatkan kumpulan tombol tetapi bagaimana saya bisa mengintegrasikannya ke dalam bidang pilih untuk html?
blub
6
ini bukan menjawab pertanyaan yang spesifik tentang JSP
Taoufik Mohdit
0

Kode di bawah ini berfungsi untuk saya

pertama saya mendefinisikan partnerTypesMapseperti di bawah ini di sisi server,

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

setelah menambahkan nilai, saya menambahkan objek ke model,

model.addAttribute("partnerTypesMap", partnerTypes);

Saat merender halaman yang saya gunakan di bawah ini foreachuntuk mencetaknya satu per satu.

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