Perché JSF salva lo stato dei componenti dell'interfaccia utente sul server?


108
  1. Fino a che punto nel tempo JSF salva lo stato dei componenti dell'interfaccia utente sul lato server e quando esattamente le informazioni sullo stato del componente dell'interfaccia utente vengono rimosse dalla memoria del server? Quando un utente connesso all'applicazione naviga attraverso le pagine, lo stato dei componenti continuerà ad accumularsi sul server?

  2. Non capisco qual è il vantaggio di mantenere lo stato dei componenti dell'interfaccia utente sul server !? Il passaggio diretto dei dati convalidati / convertiti ai bean gestiti non è sufficiente? Posso o devo cercare di evitarlo?

  3. Questo non consuma troppa memoria sul lato server, se ci sono migliaia di sessioni utente simultanee? Ho un'applicazione in cui gli utenti possono pubblicare blog su determinati argomenti. Questi blog sono di dimensioni piuttosto grandi. Quando ci saranno post back o richieste per la visualizzazione dei blog, i dati della big page verranno salvati come parte dello stato dei componenti? Ciò consumerebbe troppa memoria. Non è questo un problema?


Aggiornamento 1:

Ora, non è più necessario salvare lo stato durante l'utilizzo di JSF. È disponibile per l'uso un'implementazione JSF stateless ad alte prestazioni. Vedi questo blog e questa domanda per dettagli e discussioni rilevanti. Inoltre, c'è un problema aperto da includere nelle specifiche JSF, un'opzione per fornire la modalità senza stato per JSF. (PS Considera la possibilità di votare per i problemi questo e questo se questa è una funzione utile per te.)


Aggiornamento 2 (24-02-2013):

Una grande notizia che Mojarra 2.1.19 è uscito con la modalità senza stato !

Vedere qui:

http://weblogs.java.net/blog/mriem/archive/2013/02/08/jsf-going-stateless?force=255

http://java.net/jira/browse/JAVASERVERFACES-2731

http://balusc.blogspot.de/2013/02/stateless-jsf.html

Risposte:


199

Perché JSF deve salvare lo stato dei componenti dell'interfaccia utente sul lato server?

Perché HTTP è senza stato e JSF è con stato. L'albero dei componenti JSF è soggetto a modifiche dinamiche (programmatiche). JSF deve semplicemente conoscere lo stato esatto in cui si trovava quando il modulo è stato visualizzato all'utente finale, in modo che possa elaborare con successo l'intero ciclo di vita JSF in base alle informazioni fornite dall'albero dei componenti JSF originale quando il modulo è stato inviato di nuovo a il server. L'albero dei componenti fornisce informazioni sui nomi dei parametri di richiesta, i convertitori / validatori necessari, le proprietà del bean gestito associato e i metodi di azione.


Fino a che punto JSF salva lo stato dei componenti dell'interfaccia utente sul lato server e quando esattamente le informazioni sullo stato del componente dell'interfaccia utente vengono rimosse dalla memoria del server?

Queste due domande sembrano ridursi allo stesso. Ad ogni modo, questo è specifico dell'implementazione e dipende anche dal fatto che lo stato venga salvato sul server o sul client. Un'implementazione un po 'decente lo rimuoverà quando è scaduto o quando la coda è piena. Mojarra, ad esempio, ha un limite predefinito di 15 viste logiche quando il salvataggio dello stato è impostato su sessione. Questo è configurabile con il seguente parametro di contesto in web.xml:

<context-param>
    <param-name>com.sun.faces.numberOfLogicalViews</param-name>
    <param-value>15</param-value>
</context-param>

Vedi anche le domande frequenti su Mojarra per altri parametri specifici di Mojarra e questa risposta correlata com.sun.faces.numberOfViewsInSession vs com.sun.faces.numberOfLogicalViews


Quando un utente connesso all'applicazione naviga attraverso le pagine, lo stato dei componenti continuerà ad accumularsi sul server?

Tecnicamente, dipende dall'implementazione. Se stai parlando di navigazione da pagina a pagina (solo richieste GET), Mojarra non salverà nulla nella sessione. Se sono invece richieste POST (moduli con link / pulsanti di comando), Mojarra salverà lo stato di ogni modulo in sessione fino al limite massimo. Ciò consente all'utente finale di aprire più moduli in diverse schede del browser nella stessa sessione.

Oppure, quando il salvataggio dello stato è impostato su client, JSF non memorizzerà nulla nella sessione. Puoi farlo dal seguente parametro di contesto in web.xml:

<context-param>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>client</param-value>
</context-param>

Verrà quindi serializzato in una stringa crittografata in un campo di input nascosto con il nome javax.faces.ViewStatedel modulo.


Non capisco quale sia il vantaggio di mantenere lo stato del componente UI sul lato server. Il passaggio diretto dei dati convalidati / convertiti ai bean gestiti non è sufficiente? Posso / devo cercare di evitarlo?

Non è sufficiente per garantire l'integrità e la robustezza di JSF. JSF è un framework dinamico con un unico punto di controllo di ingresso. Senza una gestione dello stato, si sarebbe in grado parodia / mod HTTP richieste in un certo modo (ad esempio manipolazione disabled, readonlye renderedgli attributi), per far JSF fare cose diverse -e potenzialmente hazardful-. Sarebbe anche soggetto ad attacchi CSRF e phishing.


E non consumerà troppa memoria sul lato server, se ci sono migliaia di sessioni utente simultanee? Ho un'applicazione in cui gli utenti possono pubblicare blog su determinati argomenti. Questi blog sono di dimensioni piuttosto grandi. Quando ci sarà un postback o una richiesta di visualizzazione dei blog, i blog di grandi dimensioni verranno salvati come parte dello stato dei componenti. Ciò consumerebbe troppa memoria. Non è questo un problema?

La memoria è particolarmente economica. Basta dare al server delle applicazioni memoria sufficiente. Oppure, se la larghezza di banda della rete è più economica per te, cambia semplicemente il salvataggio dello stato sul lato client. Per trovare la corrispondenza migliore, basta eseguire un test di stress e profilare la tua webapp con la quantità massima prevista di utenti simultanei e quindi dare al server delle applicazioni il 125% ~ 150% della memoria massima misurata.

Nota che JSF 2.0 è migliorato molto nella gestione dello stato. È possibile salvare uno stato parziale (ad esempio, verrà salvato solo il file <h:form>invece dell'intero contenuto dall'inizio <html>alla fine). Mojarra, ad esempio, lo fa. Un modulo medio con 10 campi di input (ciascuno con un'etichetta e un messaggio) e 2 pulsanti non richiederebbe più di 1 KB. Con 15 visualizzazioni in sessione, non dovrebbe essere superiore a 15 KB per sessione. Con ~ 1000 sessioni utente simultanee, non dovrebbe essere superiore a 15 MB.

La tua preoccupazione dovrebbe essere più focalizzata sugli oggetti reali (bean gestiti e / o anche entità DB) nell'ambito della sessione o dell'applicazione. Ho visto molti codici e progetti che duplicano inutilmente l'intera tabella del database nella memoria di Java come se fosse un bean con scope di sessione in cui Java è stato utilizzato invece di SQL per filtrare / raggruppare / organizzare i record. Con ~ 1000 record, ciò supererebbe facilmente i 10 MB per sessione utente .


1
Puoi chiarire # 2? Perché l'albero dei componenti non può essere ricreato su ogni richiesta? Quale stato deve essere effettivamente memorizzato tra le richieste e perché? Sembra che l'unico motivo per salvare l'albero dei componenti tra le richieste sia per le prestazioni.
Ryan

Domanda più mirata qui: stackoverflow.com/questions/7349174/…
Ryan

La tua risposta è stata molto chiara per me! Le questioni relative alle prestazioni e alla scalabilità di JSF hanno una relazione intrinseca con l'implementazione del programmatore! È necessario sapere come utilizzare la tecnologia nel modo giusto!
Lucas Batistussi

"Dai solo abbastanza memoria al server app." Ehm, ho l'impressione che stiamo parlando di cose a livello aziendale qui, se stiamo parlando di migliaia di sessioni utente simultanee. Se hai apparecchiature di livello aziendale in un'azienda, non puoi semplicemente "dare al server delle applicazioni memoria sufficiente" come puoi fare nella tua macchina Linux a casa.
stu

La tua risposta è stata molto chiara e grazie per questo. Perché l'ambito flash JSF è scomparso se si imposta javax.faces.PARTIAL_STATE_SAVING su true. getFacesContext (). getExternalContext (). getFlash (). put ("buildingId", buildingId).
Maggio Thet
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.