Синтаксис EL для проверки, содержит ли набор конкретное значение Enum

У меня есть объект Item, у которого есть поле, которое является набором ItemTypes:

public class Item {
    EnumSet<ItemType> itemTypeSet;

    ...

    public Set<ItemType> getItemTypeSet(){
        return this.itemTypeSet;
    }
}

ItemType - это, конечно, простой Enum.

public Enum ItemType {
    BOLD, THIN, COOL, ROUND;
}

В моем JSP я хотел бы использовать JSTL, чтобы увидеть, имеет ли элемент конкретный ItemType, я попытался использовать следующие три фрагмента, но я не получаю ошибок и результатов. Я не уверен, почему все 3 терпят неудачу. Может ли кто-нибудь объяснить для каждого из этих трех случаев, почему программа не работает так, как я думаю, и предоставить четвертый вариант, который работает:)?

<c:if test="${item.itemTypeSet.contains('BOLD')}">
    Method 1 works!
</c:if>
<c:if test="${item.itemTypeSet.contains(ItemType.valueOf('BOLD'))}">
    Method 2 works!
</c:if>
<c:if test="${item.itemTypeSet.contains(ItemType.BOLD)}">
    Method 3 works!
</c:if>

Важно то, что ItemType enum общедоступен, а не внутри другого класса. Он полностью доступен для любого другого класса, включая те, которые разрешают EL/JSTL/JSP.

Обратите внимание, что перебор всех значений в enumset работает нормально:

<c:forEach items="${item.itemTypeSet}" var="itemType">
    <p>${itemType}</p>
</c:forEach>

дает в результате:

BOLD
ROUND

1 ответ

Метод 3 будет работать в EL 3.0 (Tomcat 8, WildFly 8, GlassFish 4 и т. Д. И более новые) при условии, что вы импортировали перечисление в контексте страницы JSP, как указано в разделе Как ссылаться на константы в EL?

<@page import="com.example.ItemType" %>

Метод 2 теоретически должен работать и в EL 3.0, но он неуклюж по сравнению с 3.

Метод 1 не будет работать вообще, так как EL не знает об универсальном типе коллекции и все еще предполагает, что это просто String из-за ${'...'} синтаксис. В основном это делает "BOLD".equals(BOLD) под одеялом, которое никогда не пройдет.

Для этого вам лучше всего создать собственную функцию EL. Для примера запуска пользовательской EL-функции перейдите к ответу на этот связанный вопрос: Как я могу сделать множественный выбор в jsp/jstl с выбранным значением? Вы хотели бы закончить с чем-то вроде этого:

<c:if test="${my:containsEnum(item.itemTypeSet, 'BOLD')}">

И сделать магию Java соответственно в containsEnum(Set, String) функция.

Другие вопросы по тегам