Mengapa JSF perlu menyimpan status komponen UI di sisi server?
Karena HTTP bersifat stateless dan JSF stateful. Pohon komponen JSF tunduk pada perubahan dinamis (terprogram). JSF hanya perlu mengetahui keadaan persisnya seperti ketika formulir telah ditampilkan ke pengguna akhir, sehingga dapat berhasil memproses seluruh siklus hidup JSF berdasarkan informasi yang diberikan oleh pohon komponen JSF asli ketika formulir telah dikirim kembali ke server. Pohon komponen menyediakan informasi tentang nama parameter permintaan, konverter / validator yang diperlukan, properti kacang terkelola yang terikat, dan metode tindakan.
Sampai titik mana JSF menyimpan status komponen UI di sisi server dan kapan tepatnya informasi status komponen UI dihapus dari memori server?
Kedua pertanyaan itu tampaknya bermuara pada hal yang sama. Bagaimanapun, ini adalah implementasi khusus dan juga tergantung pada apakah status disimpan di server atau klien. Implementasi yang sedikit layak akan menghapusnya ketika telah kedaluwarsa atau ketika antrian penuh. Mojarra misalnya memiliki batas default 15 tampilan logis saat penyimpanan negara diatur ke sesi. Ini dapat dikonfigurasi dengan parameter konteks berikut di web.xml
:
<context-param>
<param-name>com.sun.faces.numberOfLogicalViews</param-name>
<param-value>15</param-value>
</context-param>
Lihat juga FAQ Mojarra untuk parameter khusus Mojarra lainnya dan jawaban terkait com.sun.faces.numberOfViewsInSession vs com.sun.faces.numberOfLogicalViews
Saat pengguna yang masuk pada aplikasi menavigasi halaman, apakah status komponen akan terus terakumulasi di server?
Secara teknis, itu tergantung implementasinya. Jika Anda berbicara tentang navigasi halaman-ke-halaman (hanya DAPATKAN permintaan) maka Mojarra tidak akan menyimpan apa pun dalam sesi. Namun jika itu adalah permintaan POST (formulir dengan tautan perintah / tombol), maka Mojarra akan menyimpan status setiap formulir dalam sesi hingga batas maksimal. Hal ini memungkinkan pengguna akhir untuk membuka berbagai formulir di tab browser yang berbeda dalam sesi yang sama.
Atau, ketika penyimpanan negara diatur ke klien, maka JSF tidak akan menyimpan apa pun dalam sesi. Anda dapat melakukannya dengan parameter konteks berikut di web.xml
:
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
Ini kemudian akan diserialkan ke string terenkripsi di bidang input tersembunyi dengan nama javax.faces.ViewState
formulir.
Saya tidak mengerti apa manfaat dari mempertahankan status komponen UI di sisi server. Tidak cukupkah meneruskan data yang divalidasi / dikonversi secara langsung ke kacang yang dikelola? Bisakah / haruskah saya mencoba menghindarinya?
Itu tidak cukup untuk memastikan integritas dan ketahanan JSF. JSF adalah kerangka kerja dinamis dengan satu titik kontrol masuk. Tanpa manajemen negara, seseorang akan dapat memalsukan / meretas permintaan HTTP dengan cara tertentu (misalnya memanipulasi disabled
, readonly
dan rendered
atribut), untuk membiarkan JSF melakukan hal-hal yang berbeda -dan berpotensi berbahaya-. Bahkan rentan terhadap serangan CSRF dan phishing.
Dan bukankah itu akan menghabiskan terlalu banyak memori di sisi server, jika ada ribuan sesi pengguna secara bersamaan? Saya memiliki aplikasi tempat pengguna dapat memposting blog tentang topik tertentu. Blog ini berukuran cukup besar. Ketika akan ada posting balik atau permintaan untuk melihat blog, blog besar akan disimpan sebagai bagian dari komponen keadaan. Ini akan menghabiskan terlalu banyak memori. Bukankah ini masalah?
Memori sangat murah. Berikan saja memori yang cukup kepada server aplikasi. Atau jika bandwidth jaringan lebih murah bagi Anda, cukup alihkan penyimpanan status ke sisi klien. Untuk menemukan kecocokan terbaik, cukup uji stres dan buat profil aplikasi web Anda dengan jumlah maksimum pengguna bersamaan yang diharapkan dan kemudian berikan server aplikasi 125% ~ 150% dari memori terukur maksimum.
Perhatikan bahwa JSF 2.0 telah meningkat pesat dalam manajemen status. Hal ini dimungkinkan untuk menyimpan keadaan parsial (misalnya hanya yang <h:form>
akan disimpan, bukan seluruh hal dari <html>
semua jalan sampai akhir). Mojarra misalnya melakukan itu. Bentuk rata-rata dengan 10 bidang masukan (masing-masing dengan label dan pesan) dan 2 tombol akan membutuhkan waktu tidak lebih dari 1KB. Dengan 15 tampilan dalam sesi, itu tidak boleh lebih dari 15 KB per sesi. Dengan ~ 1000 sesi pengguna bersamaan, ukurannya tidak boleh lebih dari 15MB.
Perhatian Anda harus lebih difokuskan pada objek nyata (kacang yang dikelola dan / atau bahkan entitas DB) dalam ruang lingkup sesi atau aplikasi. Saya telah melihat banyak kode dan proyek yang tidak perlu menduplikasi seluruh tabel database ke dalam memori Java dalam bentuk kacang cakupan sesi di mana Java digunakan sebagai pengganti SQL untuk memfilter / mengelompokkan / mengatur catatan. Dengan ~ 1000 catatan, itu akan dengan mudah melebihi 10MB per sesi pengguna .