Come si ottiene la lunghezza di un elenco nel linguaggio delle espressioni JSF?


117

Come posso ottenere la lunghezza di ArrayListun'espressione JSF EL?

#{MyBean.somelist.length}

non funziona.



@GBa puoi usare # {MyBean.somelist.size ()} per visualizzare la dimensione dell'elenco.
Umair

Puoi anche usare c: forEach per scorrere l'elenco e nel corpo del ciclo assegnare il valore di conteggio a una variabile, come: <c: set var = "nr_of_items" value = "$ {varStatus.count}" />. Utile soprattutto quando stai comunque scorrendo l'elenco.
David Balažic

Risposte:


166

Sì, poiché un genio nel comitato di creazione dell'API Java ha deciso che, anche se alcune classi hanno size()membri o lengthattributi, non verranno implementate getSize()o getLength()che JSF e la maggior parte degli altri standard richiedono, non puoi fare quello che vuoi.

Ci sono un paio di modi per farlo.

Uno: aggiungi una funzione al tuo Bean che restituisca la lunghezza:

In classe MyBean:
public int getSomelistLength () {return this.somelist.length; }

Nella tua pagina JSF:
# {} MyBean.somelistLength

Due: se stai usando Facelets (Oh, Dio, perché non stai usando Facelets!), Puoi aggiungere lo spazio dei nomi fn e usare la funzione length

Nella pagina JSF:
# {fn: length (MyBean.somelist)}

2
fn è probabilmente la strada da percorrere, sfortunatamente è disponibile solo nelle versioni JSTL successive alla 1.1.
James McMahon,

27
L'uso di fn: length ha funzionato per me con JSP nudo (nessun JSF, Facelets; il progetto ultra legacy è stato leggermente aggiornato prima di essere eliminato gradualmente). Il taglib corretto da usare:<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
Christopher Parker

57
Per le persone che atterrano qui come me, ancora negli ultimi 2 anni, considera che puoi aggiungere il seguente spazio dei nomi al tuo facelet: xmlns:fn="http://java.sun.com/jsp/jstl/functions"
Damien MIRAS

59

Intendi taglia () non è vero?

#{MyBean.somelist.size()}

funziona per me (usando JBoss Seam che ha le estensioni Jboss EL)


Forse le specifiche più recenti dell'EL supportano il metodo delle dimensioni? Qualcuno può confermarlo o negarlo?
James McMahon

2
@nemo - questo problema viene affrontato in una versione di manutenzione JSR245: blogs.sun.com/kchung/entry/jsr_245_mr_part_i (In termini di specifiche JEE, sarà JEE6)
McDowell

@ McDowell, grazie per le informazioni, sono davvero sorpreso che ci sia voluto così tanto tempo per risolvere il problema.
James McMahon

Grazie. Ha funzionato anche per me. +1. Ma fino a quando JEE 6 non sarà ampiamente supportato, probabilmente continuerò a utilizzare la funzione JSTL "più standard".
Hosam Aly

A proposito, probabilmente funziona in JBoss solo per dire #{MyBean.somelist.size}(senza parentesi alla fine).
Hosam Aly,

14

Nota: questa soluzione è migliore per le versioni precedenti di JSTL. Per le versioni successive alla 1.1 vi consiglio di utilizzare fn:length(MyBean.somelist)come suggerito da Bill James .


Questo articolo contiene alcune informazioni più dettagliate, inclusa un'altra possibile soluzione;

Il problema è che stiamo cercando di invocare il metodo size dell'elenco (che è un metodo LinkedList valido), ma non è un metodo getter conforme a JavaBeans, quindi l'espressione list.size-1 non può essere valutata.

Ci sono due modi per affrontare questo dilemma. Innanzitutto, puoi utilizzare la libreria RT Core, in questo modo:

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

In secondo luogo, se si desidera evitare il codice Java nelle pagine JSP, è possibile implementare una semplice classe wrapper che contiene un elenco e fornisce l'accesso alla proprietà size dell'elenco con un metodo getter conforme a JavaBeans. Quel bean è elencato nel Listato 2.25.

Il problema con il metodo c_rt è che è necessario ottenere manualmente la variabile dalla richiesta, perché altrimenti non la riconosce. A questo punto stai inserendo molto codice per ciò che dovrebbe essere integrato nella funzionalità. Questo è un difetto GIGANTE nell'EL.

Ho finito per usare il metodo "wrapper", ecco la classe per questo;

public class CollectionWrapper {

    Collection collection;

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

    public Collection getCollection() {
        return collection;
    }

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

Una terza opzione che nessuno ha ancora menzionato è inserire la dimensione dell'elenco nel modello (supponendo che tu stia utilizzando MVC) come attributo separato. Quindi nel tuo modello avresti "someList" e poi "someListSize". Questo potrebbe essere il modo più semplice per risolvere questo problema.



6
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>

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

Sullo schermo mostra le dimensioni della tabella

Esempio: Table Size = 5


Sì, trovo che sia il modo più semplice per farlo. Sto usando websphere6 con JSP (sistema legacy). ha usato lo stesso tablib e poi usa il "simbolo del dollaro" invece di "hash" perché l'hash non ha funzionato. es: {fn: length (SystemBean.list)}
JackDev

0

Puoi eventualmente estendere il linguaggio EL utilizzando EL Functor , che ti consentirà di chiamare qualsiasi metodo Java bean, anche con parametri ...


-1

Dopo 7 anni ... la soluzione facelets funziona ancora bene per me come utente jsf

includere lo spazio dei nomi come xmlns:fn="http://java.sun.com/jsp/jstl/functions"

e usa EL come #{fn:length(myBean.someList)}per esempio se usando in jsf ui: il frammento sotto l'esempio funziona bene

<ui:fragment rendered="#{fn:length(myBean.someList) gt 0}">
    <!-- Do something here-->
</ui:fragment>

-5

È possibile ottenere la lunghezza utilizzando il seguente EL:

# {Bean.list.size ()}


1
Questa è essenzialmente la stessa risposta di Damo .
Artjom B.

6
Come @ArtjomB. suggerimenti, non è generalmente buono qui pubblicare ciò che equivale alla stessa risposta di qualcun altro già pubblicato. In questo caso, quasi sei anni fa .
Andrew Barber
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.