JSP'de bir HashMap'te nasıl döngü yapılır?


148

Bir HashMapJSP'de nasıl döngü yapabilirim ?

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

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

17
Bu arada, a HashMapdoğası gereği sırasızdır. İhtiyaç duymadığınızdan TreeMap(anahtara göre otomatik sıralama) veya LinkedHashMap(ekleme sırasını korur) emin misiniz?
BalusC

Yanıtlar:


310

Normal Java kodunda yaptığınız gibi.

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

Ancak , komut dosyaları (JSP dosyalarındaki ham Java kodu, bu tür <% %>şeyler) kötü bir uygulama olarak kabul edilir . Ben yüklemeye tavsiye JSTL (sadece JAR dosyası açılır /WEB-INF/libve gerekli beyan taglibs JSP üst tarafında). <c:forEach>Diğerleri arasında yinelenebilen bir etiketi vardır Map. Her yineleme size Map.Entrysırayla getKey()ve getValue()yöntemleri olan bir geri dönüş verecektir .

İşte temel bir örnek:

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

Böylelikle sorununuz şu şekilde çözülebilir:

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

İstenilen kapsamda yerleştirmek için a Servletveya a'ya ihtiyacınız var . Bu listenin isteğe dayalı olması gerekiyorsa, 's' i kullanın :ServletContextListener${countries}ServletdoGet()

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

Veya bu listenin uygulama çapında sabit olması gerekiyorsa, ServletContextListener's' i kullanın, contextInitialized()böylece yalnızca bir kez yüklenecek ve bellekte tutulacaktır:

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

Her iki durumda da countriessatışa sunulacak EL tarafından ${countries}.

Bu yardımcı olur umarım.

Ayrıca bakınız:


2
@Khue: evet, oturuma öznitelikler de koyabilirsiniz. Yalnızca neden birden çok oturumda uygulama genelindeki verileri kopyalamak istediğinizi anlamıyorum.
BalusC

Oturuma dayalı bilgi durumunda düşünüyorum. Çok güzel açıklama için teşekkürler.
Khue Vu

Eminim yanıt açıktır, ancak - senaryolar neden kötü uygulama olarak kabul ediliyor? Eski bir uygulamanın sürdürülmesinden dolayı JSTL'nin olmaması durumunda, bu benim tek seçeneğim.
Zibbobz

@Zibbobz: "zayıf uygulama" metni bir bağlantıdır. Üstüne tıkla.
BalusC

2

Döngü içinde neyi başarmak istediğinize bağlı olarak, bunun yerine şunlardan birini yineleyin:

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

evet, bununla tüm anahtar setini elde ederim, ancak bunu html için bir seçme alanına nasıl entegre edebilirim?
blub

6
bu
JSP'ye

0

Aşağıdaki kod benim için çalışıyor

önce partnerTypesMapsunucu tarafında aşağıdaki gibi tanımladım ,

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

buna değerlerinin toplanması sonra nesne eklendi model,

model.addAttribute("partnerTypesMap", partnerTypes);

Sayfayı oluştururken aşağıda foreachtek tek yazdırmak için kullanıyorum .

<c:forEach items="${partnerTypesMap}" var="partnerTypesMap">
      <form:option value="${partnerTypesMap['value']}">${partnerTypesMap['key']}</form:option>
</c:forEach>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.