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.ViewState
del 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
, readonly
e rendered
gli 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 .