Як пройти цикл через HashMap в JSP?


146

Як я можу пройти цикл через HashMapJSP?

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

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

17
До речі, a HashMapє за своєю природою не упорядкованим. Ви впевнені, що вам не потрібно TreeMap(автоматичне сортування за ключем) або LinkedHashMap(підтримує порядок вставки)?
BalusC

Відповіді:


308

Так само, як і в звичайному Java-коді.

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

Тим НЕ менше , скріптлети (сирої код Java в JSP - файлах, ці <% %>речі) вважається поганою практикою . Я рекомендую встановити JSTL (просто занесіть файл JAR до /WEB-INF/libта оголосьте потрібні таліби вгорі JSP). Він має <c:forEach>тег, який може перебирати серед інших Maps. Кожна ітерація дасть вам Map.Entryзворотній бік, який у свою чергу має getKey()і getValue()методи.

Ось основний приклад:

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

Таким чином, ваше конкретне питання можна вирішити наступним чином:

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

Для розміщення потрібного обсягу вам потрібно a Servletабо a . Якщо цей список повинен бути запит на основі, а потім використовувати «s :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);
}

Або якщо цей список повинен бути постійною програмою, тоді використовуйте ServletContextListenerйого contextInitialized()так, що він буде завантажений лише один раз і зберігатиметься в пам'яті:

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

В обох випадках countriesвипуск буде доступний в EL від ${countries}.

Сподіваюся, це допомагає.

Дивитися також:


2
@Khue: так, ви також можете розміщувати атрибути в сеансі. Я лише не бачу, чому ви хочете дублювати дані, що стосуються додатків, протягом декількох сеансів.
BalusC

Я думаю, що у випадку інформації на основі сеансу. Дякую за дуже приємне пояснення.
Khue Vu

Я впевнений, що відповідь очевидна, але - чому сценарії вважаються поганою практикою? За відсутності JSTL через підтримку застарілого додатка, це єдиний мій варіант.
Зіббобз

@Zibbobz: текст "погана практика" - це посилання. Натисніть на нього.
BalusC

1

Залежно від того, що ви хочете виконати в циклі, замість цього повторіть один із них:

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

так, з цим я отримую набір ключів але, але як я можу інтегрувати його у поле вибору для html?
blub

6
це не відповідає на питання, яке стосується JSP
Taoufik Mohdit

0

Нижче код працює для мене

спочатку я визначив partnerTypesMapподібне нижче на стороні сервера,

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

після додавання значень до нього я додав об'єкт model,

model.addAttribute("partnerTypesMap", partnerTypes);

Під час надання сторінки я використовую нижче, foreachщоб друкувати їх по черзі.

<c:forEach items="${partnerTypesMap}" var="partnerTypesMap">
      <form:option value="${partnerTypesMap['value']}">${partnerTypesMap['key']}</form:option>
</c:forEach>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.