Jak uzyskać długość listy w języku wyrażeń JSF?

118

Jak uzyskać długość ArrayListprzy użyciu wyrażenia JSF EL?

#{MyBean.somelist.length}

nie działa.

GBa
źródło
@GBa możesz użyć # {MyBean.somelist.size ()}, aby wyświetlić rozmiar listy.
Umair
Możesz również użyć c: forEach, aby zapętlić listę i przypisać w treści pętli wartość licznika do zmiennej, na przykład: <c: set var = "nr_of_items" value = "$ {varStatus.count}" />. Przydatne zwłaszcza, gdy mimo wszystko przeglądasz listę w pętli.
David Balažic

Odpowiedzi:

166

Tak, ponieważ jakiś geniusz z komitetu tworzenia Java API zdecydował, że nawet jeśli niektóre klasy mają size()członków lub lengthatrybuty, nie będą implementować getSize()lub getLength()które JSF i większość innych standardów wymaga, nie możesz robić tego, co chcesz.

Można to zrobić na kilka sposobów.

Po pierwsze: dodaj funkcję do swojego Beana, która zwraca długość:

W klasie MyBean:
public int getSomelistLength () {return this.somelist.length; }

Na Twojej stronie JSF:
# {MyBean.somelistLength}

Po drugie: jeśli używasz Facelets (O Boże, dlaczego nie używasz Faceletów!), Możesz dodać przestrzeń nazw fn i użyć funkcji length

Na stronie JSF:
# {fn: length (MyBean.somelist)}
billjamesdev
źródło
2
fn jest prawdopodobnie właściwą drogą, niestety jest dostępny tylko w wersjach JSTL większych niż 1.1.
James McMahon
27
Użycie fn: length działało dla mnie z gołym JSP (bez JSF, Facelets; projekt ultra starszego typu jest lekko aktualizowany przed wycofaniem). Właściwy taglib do użycia:<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
Christopher Parker
57
Dla osób lądujących tutaj, takich jak ja, jeszcze 2 lata później, zastanów się, czy możesz dodać następującą przestrzeń nazw do swojej twarzy: xmlns:fn="http://java.sun.com/jsp/jstl/functions"
Damien MIRAS
60

Masz na myśli rozmiar (), prawda?

#{MyBean.somelist.size()}

działa dla mnie (używając JBoss Seam, który ma rozszerzenia Jboss EL)

Damo
źródło
Może nowsze specyfikacje EL obsługują metodę rozmiaru? Czy ktoś może to potwierdzić lub zaprzeczyć?
James McMahon
2
@nemo - jest to rozwiązywane w wydaniu konserwacyjnym JSR245: blogs.sun.com/kchung/entry/jsr_245_mr_part_i (W zakresie specyfikacji JEE będzie to JEE6)
McDowell
@McDowell, Dzięki za informację, jestem naprawdę zaskoczony, że zajęło im tak dużo czasu, zanim rozwiązali problem.
James McMahon
Dziękuję Ci. Mnie też się udało. +1. Ale dopóki JEE 6 nie będzie szeroko obsługiwany, prawdopodobnie będę trzymać się „bardziej standardowej” funkcji JSTL.
Hosam Aly
Swoją drogą, prawdopodobnie działa w JBoss #{MyBean.somelist.size}(bez nawiasów na końcu).
Hosam Aly
14

Uwaga: to rozwiązanie jest lepsze dla starszych wersji JSTL. W przypadku wersji powyżej 1.1 polecam używanie fn:length(MyBean.somelist)zgodnie z sugestią Billa Jamesa .


Ten artykuł zawiera bardziej szczegółowe informacje, w tym inne możliwe rozwiązanie;

Problem polega na tym, że próbujemy wywołać metodę rozmiaru listy (która jest poprawną metodą LinkedList), ale nie jest to metoda pobierająca zgodna z JavaBeans, więc wyrażenie list.size-1 nie może zostać ocenione.

Istnieją dwa sposoby rozwiązania tego dylematu. Po pierwsze, możesz użyć biblioteki RT Core, na przykład:

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

Po drugie, jeśli chcesz uniknąć kodu Java na stronach JSP, możesz zaimplementować prostą klasę opakowującą, która zawiera listę i zapewnia dostęp do właściwości size listy za pomocą metody pobierającej zgodnej z JavaBeans. Ta fasola jest wymieniona na liście 2.25.

Problem z metodą c_rt polega na tym, że musisz ręcznie pobrać zmienną z żądania, ponieważ inaczej jej nie rozpoznaje. W tym momencie umieszczasz dużo kodu dla tego, co powinno być wbudowane w funkcjonalność. To jest OGROMNA wada EL.

Skończyło się na użyciu metody „wrapper”, oto klasa do tego;

public class CollectionWrapper {

    Collection collection;

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

    public Collection getCollection() {
        return collection;
    }

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

Trzecią opcją, o której nikt jeszcze nie wspomniał, jest umieszczenie rozmiaru listy w modelu (zakładając, że używasz MVC) jako oddzielnego atrybutu. Więc w swoim modelu powinieneś mieć „someList”, a następnie „someListSize”. To może być najprostszy sposób rozwiązania tego problemu.

James McMahon
źródło
6
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>

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

Na ekranie wyświetla rozmiar tabeli

Przykład: Table Size = 5

UdayKiran Pulipati
źródło
Tak, to najprostszy sposób na zrobienie tego. Używam websphere6 z JSP (starszy system). użył tego samego tablib, a następnie użyj „znaku dolara” zamiast „hash”, ponieważ hash nie zadziałał. tj .: {fn: length (SystemBean.list)}
JackDev
0

Możesz ostatecznie rozszerzyć język EL, używając EL Functor , który pozwoli ci wywołać dowolne metody Java Bean, nawet z parametrami ...

Romain Linsolas
źródło
-1

Po 7 latach ... rozwiązanie facelets nadal działa dobrze dla mnie jako użytkownika jsf

uwzględnij przestrzeń nazw jako xmlns:fn="http://java.sun.com/jsp/jstl/functions"

i użyj EL tak, jak #{fn:length(myBean.someList)}na przykład jeśli używasz w jsf ui: fragment poniższego przykładu działa dobrze

<ui:fragment rendered="#{fn:length(myBean.someList) gt 0}">
    <!-- Do something here-->
</ui:fragment>
Arry
źródło
-5

Możesz uzyskać długość za pomocą następującego EL:

# {Bean.list.size ()}

Soujanya
źródło
1
Jest to zasadniczo ta sama odpowiedź, co odpowiedź Damo .
Artjom B.
6
Jak @ArtjomB. sugestie, generalnie nie jest dobrze publikować w tym miejscu, co sprowadza się do takiej samej odpowiedzi, jaką opublikował ktoś inny. W tym przypadku prawie sześć lat temu .
Andrew Barber