Bagaimana Anda mendapatkan panjang daftar dalam bahasa ekspresi JSF?

118

Bagaimana saya mendapatkan panjang dari ArrayListekspresi JSF EL?

#{MyBean.somelist.length}

tidak bekerja.

GBa
sumber
@GBa Anda dapat menggunakan # {MyBean.somelist.size ()} untuk menampilkan ukuran daftar.
Umair
Anda juga bisa menggunakan c: forEach untuk mengulang daftar dan di badan perulangan menetapkan nilai hitungan ke variabel, seperti: <c: set var = "nr_of_items" value = "$ {varStatus.count}" />. Berguna terutama ketika Anda mengulang daftar itu.
David Balažic

Jawaban:

166

Ya, karena beberapa jenius dalam komite pembuatan Java API memutuskan bahwa, meskipun kelas tertentu memiliki size()anggota atau lengthatribut, mereka tidak akan menerapkan getSize()atau getLength()yang dibutuhkan JSF dan sebagian besar standar lainnya, Anda tidak dapat melakukan apa yang Anda inginkan.

Ada beberapa cara untuk melakukan ini.

Satu: tambahkan fungsi ke Bean Anda yang mengembalikan panjang:

Di kelas MyBean:
public int getSomelistLength () {return this.somelist.length; }

Di halaman JSF Anda:
# {MyBean.somelistLength}

Dua: Jika Anda menggunakan Facelet (Ya Tuhan, mengapa Anda tidak menggunakan Facelet!), Anda dapat menambahkan namespace fn dan menggunakan fungsi panjang

Di halaman JSF:
# {fn: length (MyBean.somelist)}
billjamesdev
sumber
2
fn mungkin cara yang tepat, sayangnya ini hanya tersedia di versi JSTL yang lebih besar dari 1.1.
James McMahon
27
Menggunakan fn: length bekerja untuk saya dengan JSP kosong (tanpa JSF, Facelet; proyek ultra legacy diperbarui dengan ringan sebelum dihapus secara bertahap). Taglib yang tepat untuk digunakan:<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
Christopher Parker
57
Untuk orang yang mendarat di sini seperti saya, masih 2 tahun terakhir, pertimbangkan Anda dapat menambahkan namespace berikut ke facelet Anda: xmlns:fn="http://java.sun.com/jsp/jstl/functions"
Damien MIRAS
60

Maksud Anda ukuran () bukan?

#{MyBean.somelist.size()}

berfungsi untuk saya (menggunakan JBoss Seam yang memiliki ekstensi Jboss EL)

Damo
sumber
Mungkin spesifikasi EL yang lebih baru mendukung metode ukuran? Adakah yang bisa mengkonfirmasi atau menyangkal ini?
James McMahon
2
@nemo - ini sedang ditangani dalam rilis pemeliharaan JSR245: blogs.sun.com/kchung/entry/jsr_245_mr_part_i (Dalam hal spesifikasi JEE, itu akan menjadi JEE6)
McDowell
@McDowell, Terima kasih atas infonya, saya benar-benar terkejut karena mereka butuh waktu selama ini untuk menyelesaikan masalah.
James McMahon
Terima kasih. Itu berhasil untuk saya juga. +1. Tetapi hingga JEE 6 didukung secara luas, saya mungkin akan tetap menggunakan fungsi JSTL yang "lebih standar".
Hosam Aly
BTW, mungkin berfungsi di JBoss untuk hanya mengatakannya #{MyBean.somelist.size}(tanpa tanda kurung di akhir).
Hosam Aly
14

Catatan: Solusi ini lebih baik untuk versi JSTL yang lebih lama. Untuk versi yang lebih besar dari 1.1 saya sarankan menggunakan fn:length(MyBean.somelist)seperti yang disarankan oleh Bill James .


Artikel ini memiliki beberapa informasi yang lebih rinci, termasuk solusi lain yang mungkin;

Masalahnya adalah kita mencoba memanggil metode ukuran daftar (yang merupakan metode LinkedList yang valid), tetapi itu bukan metode pengambil yang sesuai dengan JavaBeans, sehingga ekspresi list.size-1 tidak dapat dievaluasi.

Ada dua cara untuk mengatasi dilema ini. Pertama, Anda dapat menggunakan pustaka RT Core, seperti ini:

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

Kedua, jika Anda ingin menghindari kode Java di halaman JSP, Anda dapat mengimplementasikan kelas pembungkus sederhana yang berisi daftar dan menyediakan akses ke properti ukuran daftar dengan metode pengambil yang sesuai dengan JavaBeans. Kacang itu terdaftar di Listing 2.25.

Masalah dengan metode c_rt adalah Anda perlu mendapatkan variabel dari permintaan secara manual, karena metode ini tidak mengenalinya. Pada titik ini Anda memasukkan banyak kode untuk apa yang harus dibangun dalam fungsionalitas. Ini adalah cacat RAKSASA di EL.

Saya akhirnya menggunakan metode "pembungkus", inilah kelas untuk itu;

public class CollectionWrapper {

    Collection collection;

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

    public Collection getCollection() {
        return collection;
    }

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

Opsi ketiga yang belum disebutkan oleh siapa pun adalah memasukkan ukuran daftar Anda ke dalam model (dengan asumsi Anda menggunakan MVC) sebagai atribut terpisah. Jadi dalam model Anda, Anda akan memiliki "someList" dan kemudian "someListSize". Itu mungkin cara paling sederhana untuk mengatasi masalah ini.

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

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

Di layar ini menampilkan ukuran Tabel

Contoh: Table Size = 5

UdayKiran Pulipati
sumber
Ya, ini menurut saya adalah cara termudah untuk melakukannya. Saya menggunakan websphere6 dengan JSP (sistem warisan). menggunakan tablib yang sama dan kemudian menggunakan 'tanda dolar' sebagai lawan dari 'hash' karena hash tidak berfungsi. yaitu: {fn: length (SystemBean.list)}
JackDev
0

Anda akhirnya dapat memperluas bahasa EL dengan menggunakan EL Functor , yang memungkinkan Anda memanggil metode kacang Java apa pun, bahkan dengan parameter ...

Romain Linsolas
sumber
-1

Setelah 7 tahun ... solusi facelet masih berfungsi dengan baik untuk saya sebagai pengguna jsf

sertakan namespace sebagai xmlns:fn="http://java.sun.com/jsp/jstl/functions"

dan gunakan EL sebagai #{fn:length(myBean.someList)}contoh jika menggunakan di jsf ui: contoh fragmen di bawah berfungsi dengan baik

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

Anda bisa mendapatkan panjangnya menggunakan EL berikut:

# {Bean.list.size ()}

Soujanya
sumber
1
Ini pada dasarnya adalah jawaban yang sama dengan Damo .
Artjom B.
6
Sebagai @ArtjomB. Suggests, umumnya tidak baik di sini untuk memposting jawaban yang sama dengan yang sudah diposting orang lain. Dalam kasus ini, hampir enam tahun lalu .
Andrew Barber