¿Cómo se obtiene la longitud de una lista en el lenguaje de expresión JSF?

117

¿Cómo obtendría la longitud de una ArrayListexpresión JSF EL?

#{MyBean.somelist.length}

No funciona.

GBa
fuente
@GBa puede usar # {MyBean.somelist.size ()} para mostrar el tamaño de la lista.
Umair
También puede usar c: forEach para recorrer la lista y en el cuerpo del bucle asignar el valor de recuento a una variable, como: <c: set var = "nr_of_items" value = "$ {varStatus.count}" />. Útil especialmente cuando está recorriendo la lista de todos modos.
David Balažic

Respuestas:

166

Sí, ya que algún genio del comité de creación de la API de Java decidió que, aunque ciertas clases tienen size()miembros o lengthatributos, no se implementarán getSize()o getLength()que JSF y la mayoría de los otros estándares requieren, no puede hacer lo que quiere.

Hay un par de formas de hacer esto.

Uno: agregue una función a su Bean que devuelva la longitud:

En clase MyBean:
public int getSomelistLength () {return this.somelist.length; }

En su página JSF:
# {MyBean.somelistLength}

Dos: si está usando Facelets (¡Oh, Dios, por qué no está usando Facelets!), Puede agregar el espacio de nombres fn y usar la función de longitud

En la página JSF:
# {fn: length (MyBean.somelist)}
billjamesdev
fuente
2
fn es probablemente el camino a seguir, desafortunadamente solo está disponible en versiones JSTL superiores a 1.1.
James McMahon
27
El uso de fn: length funcionó para mí con JSP desnudo (sin JSF, Facelets; el proyecto ultra heredado se actualizó ligeramente antes de ser eliminado). El taglib adecuado para usar:<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
Christopher Parker
57
Para las personas que aterrizan aquí como yo, aún 2 años después, consideren que pueden agregar el siguiente espacio de nombres a su facelet: xmlns:fn="http://java.sun.com/jsp/jstl/functions"
Damien MIRAS
59

¿Te refieres al tamaño () no?

#{MyBean.somelist.size()}

funciona para mí (usando JBoss Seam que tiene las extensiones Jboss EL)

Damo
fuente
¿Quizás las especificaciones más nuevas del EL apoyan el método del tamaño? ¿Alguien puede confirmar o negar esto?
James McMahon
2
@nemo: esto se está abordando en una versión de mantenimiento JSR245: blogs.sun.com/kchung/entry/jsr_245_mr_part_i (en términos de especificaciones JEE, será JEE6)
McDowell
@McDowell, Gracias por la información, estoy realmente sorprendido de que hayan tardado tanto en solucionar el problema.
James McMahon
Gracias. También funcionó para mí. +1. Pero hasta que JEE 6 sea ampliamente compatible, probablemente me quedo con la función JSTL "más estándar".
Hosam Aly
Por cierto, probablemente funcione en JBoss solo decir #{MyBean.somelist.size}(sin el paréntesis al final).
Hosam Aly
14

Nota: esta solución es mejor para versiones anteriores de JSTL. Para versiones superiores a 1.1, recomiendo usar fn:length(MyBean.somelist)como lo sugiere Bill James .


Este artículo tiene información más detallada, incluida otra posible solución;

El problema es que estamos tratando de invocar el método de tamaño de la lista (que es un método válido de LinkedList), pero no es un método getter compatible con JavaBeans, por lo que la expresión list.size-1 no se puede evaluar.

Hay dos formas de abordar este dilema. Primero, puede usar la biblioteca RT Core, así:

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

En segundo lugar, si desea evitar el código Java en sus páginas JSP, puede implementar una clase contenedora simple que contenga una lista y proporcione acceso a la propiedad de tamaño de la lista con un método getter compatible con JavaBeans. Ese bean está listado en el Listado 2.25.

El problema con el método c_rt es que necesita obtener la variable de la solicitud manualmente, porque de lo contrario no la reconoce. En este punto, está ingresando mucho código para lo que debería integrarse en la funcionalidad. Este es un defecto GIGANTE en EL.

Terminé usando el método "envoltorio", aquí está la clase para ello;

public class CollectionWrapper {

    Collection collection;

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

    public Collection getCollection() {
        return collection;
    }

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

Una tercera opción que nadie ha mencionado todavía es poner el tamaño de su lista en el modelo (asumiendo que está usando MVC) como un atributo separado. Entonces, en su modelo tendría "someList" y luego "someListSize". Esa puede ser la forma más sencilla de resolver este problema.

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

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

En pantalla muestra el tamaño de la mesa

Ejemplo: Table Size = 5

UdayKiran Pulipati
fuente
Sí, creo que es la forma más sencilla de hacerlo. Estoy usando websphere6 con JSP (sistema heredado). usó el mismo tablib y luego usó el 'signo de dólar' en lugar de 'hash' porque el hash no funcionó. es decir: {fn: length (SystemBean.list)}
JackDev
0

Eventualmente, puede extender el lenguaje EL utilizando EL Functor , que le permitirá llamar a cualquier método de beans de Java, incluso con parámetros ...

Romain Linsolas
fuente
-1

Después de 7 años ... la solución de facelets todavía funciona bien para mí como usuario de jsf

incluir el espacio de nombres como xmlns:fn="http://java.sun.com/jsp/jstl/functions"

y use el EL como, #{fn:length(myBean.someList)}por ejemplo, si lo usa en jsf ui: el fragmento debajo del ejemplo funciona bien

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

Puede obtener la longitud utilizando el siguiente EL:

# {Bean.list.size ()}

Soujanya
fuente
1
Esta es esencialmente la misma respuesta que la de Damo .
Artjom B.
6
Como @ArtjomB. sugiere, generalmente no es bueno publicar aquí lo que equivale a la misma respuesta que alguien más ya publicó. En este caso, hace casi seis años .
Andrew Barber