Como você obtém o comprimento de uma lista na linguagem de expressão JSF?

117

Como obteria o comprimento de um ArrayListusando uma expressão JSF EL?

#{MyBean.somelist.length}

não funciona.

GBa
fonte
@GBa você pode usar # {MyBean.somelist.size ()} para exibir o tamanho da lista.
Umair de
Você também pode usar c: forEach para percorrer a lista e, no corpo do loop, atribuir o valor de contagem a uma variável, como: <c: set var = "nr_of_items" value = "$ {varStatus.count}" />. Útil especialmente quando você está repetindo a lista de qualquer maneira.
David Balažic

Respostas:

166

Sim, uma vez que algum gênio no comitê de criação da API Java decidiu que, embora certas classes tenham size()membros ou lengthatributos, eles não irão implementar getSize()ou getLength()que JSF e a maioria dos outros padrões exigem, você não pode fazer o que deseja.

Existem algumas maneiras de fazer isso.

Um: adicione uma função ao seu Bean que retorne o comprimento:

Na aula MyBean:
public int getSomelistLength () {return this.somelist.length; }

Em sua página JSF:
# {MyBean.somelistLength}

Dois: se você estiver usando Facelets (ah, meu Deus, por que não está usando Facelets!), Você pode adicionar o namespace fn e usar a função de comprimento

Na página JSF:
# {fn: length (MyBean.somelist)}
billjamesdev
fonte
2
fn é provavelmente o caminho a percorrer, infelizmente só está disponível nas versões JSTL superiores a 1.1.
James McMahon
27
Usar fn: length funcionou para mim com JSP simples (sem JSF, Facelets; projeto ultra legado sendo ligeiramente atualizado antes de ser descontinuado). O taglib adequado para usar:<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
Christopher Parker
57
Para pessoas que chegaram aqui como eu, ainda 2 anos depois, considere em adicionar o seguinte namespace ao seu facelet:xmlns:fn="http://java.sun.com/jsp/jstl/functions"
Damien MIRAS
59

Você quer dizer tamanho () não é?

#{MyBean.somelist.size()}

funciona para mim (usando JBoss Seam que tem as extensões Jboss EL)

Damo
fonte
Talvez as especificações mais recentes do EL suportem o método do tamanho? Alguém pode confirmar ou negar isto?
James McMahon,
2
@nemo - isso está sendo tratado em uma versão de manutenção JSR245: blogs.sun.com/kchung/entry/jsr_245_mr_part_i (em termos de especificações JEE, será JEE6)
McDowell
@McDowell, Obrigado pela informação, estou realmente surpreso que eles demoraram tanto para resolver o problema.
James McMahon,
Obrigado. Funcionou para mim também. +1. Mas até que o JEE 6 seja amplamente suportado, provavelmente ficarei com a função JSTL "mais padrão".
Hosam Aly
BTW, provavelmente funciona no JBoss apenas para dizer #{MyBean.somelist.size}(sem o parêntese no final).
Hosam Aly
14

Nota: Esta solução é melhor para versões mais antigas do JSTL. Para versões superiores a 1.1, recomendo usar fn:length(MyBean.somelist)conforme sugerido por Bill James .


Este artigo contém algumas informações mais detalhadas, incluindo outra solução possível;

O problema é que estamos tentando invocar o método de tamanho da lista (que é um método LinkedList válido), mas não é um método getter compatível com JavaBeans, portanto, a expressão list.size-1 não pode ser avaliada.

Existem duas maneiras de resolver esse dilema. Primeiro, você pode usar a biblioteca RT Core, assim:

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

Em segundo lugar, se quiser evitar o código Java em suas páginas JSP, você pode implementar uma classe de wrapper simples que contém uma lista e fornece acesso à propriedade size da lista com um método getter compatível com JavaBeans. Esse bean está listado na Listagem 2.25.

O problema com o método c_rt é que você precisa obter a variável do pedido manualmente, porque ele não a reconhece de outra forma. Neste ponto, você está inserindo uma grande quantidade de código para o que deve ser integrado à funcionalidade. Esta é uma falha GIGANTE no EL.

Acabei usando o método "wrapper", aqui está a aula para isso;

public class CollectionWrapper {

    Collection collection;

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

    public Collection getCollection() {
        return collection;
    }

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

Uma terceira opção que ninguém mencionou ainda é colocar o tamanho da lista no modelo (presumindo que você esteja usando MVC) como um atributo separado. Portanto, em seu modelo, você teria "someList" e "someListSize". Essa pode ser a maneira mais simples de resolver esse problema.

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

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

Na tela mostra o tamanho da mesa

Exemplo: Table Size = 5

UdayKiran Pulipati
fonte
Sim, acho que é a maneira mais simples de fazer isso. Estou usando o websphere6 com JSP (sistema legado). usou o mesmo tablib e, em seguida, use o 'cifrão' em vez de 'hash' porque o hash não funcionou. ou seja: {fn: length (SystemBean.list)}
JackDev
0

Você pode eventualmente estender a linguagem EL usando o EL Functor , que permitirá que você chame quaisquer métodos de Java beans, mesmo com parâmetros ...

Romain Linsolas
fonte
-1

Após 7 anos ... a solução facelets ainda funciona bem para mim como um usuário jsf

inclua o namespace como xmlns:fn="http://java.sun.com/jsp/jstl/functions"

e usar o EL como #{fn:length(myBean.someList)}por exemplo se usar em jsf ui: o fragmento abaixo do exemplo funciona bem

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

Você pode obter o comprimento usando o seguinte EL:

# {Bean.list.size ()}

Soujanya
fonte
1
Esta é essencialmente a mesma resposta de Damo .
Artjom B.
6
Como @ArtjomB. sugere, geralmente não é bom postar aqui o que equivale à mesma resposta que outra pessoa já postou. Neste caso, quase seis anos atrás .
Andrew Barber