Làm thế nào để lặp qua HashMap trong JSP?


146

Làm thế nào tôi có thể lặp qua một HashMaptrong JSP?

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

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

17
Nhân tiện, a HashMaplà bản chất không có thứ tự. Bạn có chắc chắn không cần TreeMap(sắp xếp tự động theo khóa) hoặc LinkedHashMap(duy trì thứ tự chèn)?
BalusC

Câu trả lời:


308

Cũng giống như cách bạn làm trong mã Java thông thường.

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

Tuy nhiên , scriptlets (mã Java thô trong các tệp JSP, những <% %>thứ đó) được coi là một cách thực hành kém . Tôi khuyên bạn nên cài đặt JSTL (chỉ cần thả tệp JAR vào /WEB-INF/libvà khai báo các taglib cần thiết ở trên cùng của JSP). Nó có một <c:forEach>thẻ có thể lặp đi lặp lại giữa những người khác Map. Mỗi lần lặp sẽ cung cấp cho bạn một Map.Entrytrở lại mà lần lượt có getKey()getValue()phương thức.

Đây là một ví dụ cơ bản:

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

Do đó, vấn đề cụ thể của bạn có thể được giải quyết như sau:

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

Bạn cần một Servlethoặc một ServletContextListenerđể đặt ${countries}trong phạm vi mong muốn. Nếu danh sách này được coi là yêu cầu có trụ sở, sau đó sử dụng 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);
}

Hoặc nếu danh sách này được coi là hằng số toàn ứng dụng, thì hãy sử dụng ServletContextListenercontextInitialized()để nó chỉ được tải một lần và được giữ trong bộ nhớ:

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

Trong cả hai trường hợp, countriessẽ có sẵn trong EL bởi ${countries}.

Hi vọng điêu nay co ich.

Xem thêm:


2
@Khue: có, bạn cũng có thể đặt các thuộc tính trong phiên. Tôi chỉ không thấy lý do tại sao bạn muốn sao chép dữ liệu rộng của ứng dụng qua nhiều phiên.
BalusC

Tôi nghĩ trong trường hợp thông tin dựa trên phiên. Cảm ơn lời giải thích rất hay.
Khue Vũ

Tôi chắc chắn câu trả lời là hiển nhiên nhưng - tại sao các tập lệnh được coi là thực hành kém? Trong trường hợp không có JSTL do duy trì một ứng dụng cũ, đây là lựa chọn duy nhất của tôi.
Zibbobz

@Zibbobz: văn bản "thực hành kém" là một liên kết. Nhấn vào nó.
BalusC

1

Tùy thuộc vào những gì bạn muốn thực hiện trong vòng lặp, thay vào đó hãy lặp lại một trong những điều sau:

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

vâng, với điều này tôi nhận được bộ khóa alle nhưng làm cách nào tôi có thể tích hợp nó vào một trường chọn cho html?
blub

6
đây không phải là trả lời câu hỏi cụ thể về JSP
Taoufik Mohdit

0

Mã dưới đây làm việc cho tôi

đầu tiên tôi xác định partnerTypesMapnhư dưới đây trong phía máy chủ,

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

Sau khi thêm giá trị vào nó, tôi đã thêm đối tượng vào model,

model.addAttribute("partnerTypesMap", partnerTypes);

Khi kết xuất trang tôi sử dụng bên dưới foreachđể in từng cái một.

<c:forEach items="${partnerTypesMap}" var="partnerTypesMap">
      <form:option value="${partnerTypesMap['value']}">${partnerTypesMap['key']}</form:option>
</c:forEach>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.