Как узнать длину списка на языке выражений JSF?

118

Как мне получить длину ArrayListвыражения JSF EL?

#{MyBean.somelist.length}

не работает.

GBA
источник
@GBa вы можете использовать # {MyBean.somelist.size ()} для отображения размера списка.
Umair 06
Вы также можете использовать c: forEach для перебора списка и в теле цикла присваивать значение счетчика переменной, например: <c: set var = "nr_of_items" value = "$ {varStatus.count}" />. Это полезно, особенно когда вы все равно просматриваете список в цикле.
Давид Балажич

Ответы:

166

Да, поскольку какой-то гений в комитете по созданию Java API решил, что, даже если у определенных классов есть size()члены или lengthатрибуты, они не будут реализовывать getSize()то, getLength()что требуется JSF и большинству других стандартов, вы не можете делать то, что хотите.

Есть несколько способов сделать это.

Первый: добавьте к вашему Bean функцию, которая возвращает длину:

В классе MyBean:
public int getSomelistLength () {вернуть this.somelist.length; }

На странице JSF:
# {MyBean.somelistLength}

Два: если вы используете Facelets (о, Боже, почему вы не используете Facelets!), Вы можете добавить пространство имен fn и использовать функцию length

На странице JSF:
# {fn: length (MyBean.somelist)}
billjamesdev
источник
2
fn, вероятно, лучший вариант, к сожалению, он доступен только в версиях JSTL выше 1.1.
Джеймс МакМахон
27
Использование fn: length сработало для меня с голым JSP (без JSF, Facelets; ультра-устаревший проект слегка обновляется, прежде чем его свернуть). Правильный taglib для использования:<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
Кристофер Паркер
57
Для людей, приземляющихся здесь, как я, все еще через 2 года, подумайте, вы можете добавить следующее пространство имен на свой фейслет: xmlns:fn="http://java.sun.com/jsp/jstl/functions"
Дэмиен МИРАС
60

Вы имеете в виду размер (), не так ли?

#{MyBean.somelist.size()}

работает для меня (с использованием JBoss Seam, у которого есть расширения Jboss EL)

Дамо
источник
Может быть, новые спецификации EL поддерживают метод размера? Кто-нибудь может подтвердить или опровергнуть это?
Джеймс МакМахон,
2
@nemo - этот вопрос рассматривается в отладочном выпуске JSR245 : blogs.sun.com/kchung/entry/jsr_245_mr_part_i (с точки зрения спецификаций JEE, это будет JEE6)
МакДауэлл,
@McDowell, спасибо за информацию, я очень удивлен, что им потребовалось столько времени, чтобы решить проблему.
Джеймс МакМахон,
Спасибо. У меня это тоже сработало. +1. Но пока JEE 6 не получит широкой поддержки, я, вероятно, буду придерживаться «более стандартной» функции JSTL.
Хосам Али,
Кстати, в JBoss, вероятно, работает просто сказать #{MyBean.somelist.size}(без скобок в конце).
Хосам Али,
14

Примечание. Это решение лучше подходит для более старых версий JSTL. Для версий выше 1.1 я рекомендую использовать, fn:length(MyBean.somelist)как было предложено Биллом Джеймсом .


В этой статье есть более подробная информация, включая другое возможное решение;

Проблема в том, что мы пытаемся вызвать метод размера списка (который является допустимым методом LinkedList), но это не совместимый с JavaBeans метод получения, поэтому выражение list.size-1 не может быть вычислено.

Есть два способа решить эту дилемму. Во-первых, вы можете использовать библиотеку RT Core, например:

<c_rt:out value='<%= list[list.size()-1] %>'/>

Во-вторых, если вы хотите избежать использования кода Java на страницах JSP, вы можете реализовать простой класс-оболочку, который содержит список и обеспечивает доступ к свойству размера списка с помощью метода получения, совместимого с JavaBeans. Этот компонент представлен в Листинге 2.25.

Проблема с методом c_rt заключается в том, что вам нужно получить переменную из запроса вручную, потому что иначе он ее не распознает. На этом этапе вы вводите много кода для того, что должно быть встроено в функциональность. Это ГИГАНСКИЙ недостаток в EL.

В итоге я использовал метод "обертки", вот класс для него;

public class CollectionWrapper {

    Collection collection;

    public CollectionWrapper(Collection collection) {
        this.collection = collection;
    }

    public Collection getCollection() {
        return collection;
    }

    public int getSize() {
        return collection.size();
    }
}

Третий вариант, о котором еще никто не упомянул, - это поместить размер вашего списка в модель (при условии, что вы используете MVC) в качестве отдельного атрибута. Итак, в вашей модели у вас будет «someList», а затем «someListSize». Это может быть самый простой способ решить эту проблему.

Джеймс МакМахон
источник
также stackoverflow.com/questions/1332169/…
baybora.oren 09
6
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>

<h:outputText value="Table Size = #{fn:length(SystemBean.list)}"/>

На экране отображается размер таблицы

Пример: Table Size = 5

УдайКиран Пулипати
источник
Да, я считаю, что это самый простой способ сделать это. Я использую websphere6 с JSP (устаревшая система). использовал тот же таблиб, а затем использовал «знак доллара» вместо «хеша», потому что хеш не работал. т.е.: {fn: length (SystemBean.list)}
JackDev
0

В конечном итоге вы можете расширить язык EL с помощью EL Functor , который позволит вам вызывать любые методы Java beans, даже с параметрами ...

Ромен Линсолас
источник
-1

Через 7 лет ... решение facelets все еще отлично работает для меня как пользователя jsf

включить пространство имен как xmlns:fn="http://java.sun.com/jsp/jstl/functions"

и используйте EL, #{fn:length(myBean.someList)}например, при использовании в jsf ui: фрагмент ниже работает нормально

<ui:fragment rendered="#{fn:length(myBean.someList) gt 0}">
    <!-- Do something here-->
</ui:fragment>
Arry
источник
-5

Вы можете получить длину, используя следующий EL:

# {Bean.list.size ()}

Soujanya
источник
1
По сути, это тот же ответ, что и у Дамо .
Artjom B.
6
Как @ArtjomB. наводит на мысль, что здесь обычно нехорошо публиковать то, что соответствует тому же ответу, что и кто-то уже отправил. При этом почти шесть лет назад .
Эндрю Барбер