Come funziona l’attributo ‘binding’ in JSF? Quando e come dovrebbe essere usato?

Ci sono molti materiali là fuori che differenziano l’attributo del value e binding attributo di binding in JSF.

Sono interessato a come entrambi gli approcci differiscono l’uno dall’altro. Dato:

 public class User { private String name; private UICommand link; // Getters and setters omitted. } 
    

È piuttosto semplice ciò che accade quando viene specificato un attributo value . Il getter viene eseguito per restituire il valore della proprietà name del bean User . Il valore è stampato sull’output HTML.

Ma non riuscivo a capire come funziona il binding . In che modo l’HTML generato mantiene un legame con la proprietà link del bean User ?

Di seguito è riportata la parte rilevante dell’output generato dopo l’abbellimento manuale e i commenti (si noti che l’id j_id_jsp_1847466274_1 stato generato automaticamente e che sono presenti due widget di input nascosti). Sto usando Sun’s JSF RI, versione 1.2.

 
Name

Dove è memorizzato il binding qui?

    Come funziona?

    Quando una vista JSF (file Facelets / JSP) viene creata / ripristinata, verrà prodotto un albero di componenti JSF. In quel momento, il tempo di creazione della vista , vengono valutati tutti binding attributi di binding ( insieme agli attributi id e ai taghandler come JSTL ). Quando il componente JSF deve essere creato prima di essere aggiunto all’albero dei componenti, JSF controllerà se l’attributo di binding restituisce un componente precreated (cioè non null ) e in tal caso, quindi usarlo. Se non è pre-elaborato, JSF creerà automaticamente il componente “nel solito modo” e invocherà il setter dietro binding attributo di bind con l’istanza del componente autocreato come argomento.

    In effetti, associa un riferimento dell’istanza del componente nell’albero dei componenti a una variabile con ambito. Questa informazione non è in alcun modo visibile nella rappresentazione HTML generata del componente stesso. Questa informazione non è in alcun modo rilevante per l’output HTML generato comunque. Quando il modulo viene inviato e la vista viene ripristinata, l’albero dei componenti JSF viene ricostruito da zero e tutti binding attributi di binding saranno semplicemente rivalutati come descritto nel paragrafo precedente. Dopo che l’albero dei componenti è stato ricreato, JSF ripristinerà lo stato della vista JSF nell’albero dei componenti.

    Le istanze del componente sono scope scope!

    Importante sapere e capire è che le istanze dei componenti concreti sono effettivamente richieste per l’ambito. Sono appena creati su ogni richiesta e le loro proprietà sono riempite con valori dallo stato di visualizzazione JSF durante la fase di visualizzazione di ripristino. Pertanto, se si associa il componente a una proprietà di un bean di supporto, il bean di backing non deve assolutamente trovarsi in un ambito più ampio rispetto all’ambito della richiesta. Vedi anche il capitolo 3.1.5 sulla specificazione di JSF 2.0 :

    3.1.5 Collegamenti dei componenti

    I collegamenti dei componenti vengono spesso utilizzati in congiunzione con JavaBeans che vengono creati in modo dinamico tramite la funzione di creazione dei bean gestiti (vedere la Sezione 5.8.1 “VariableResolver e Default VariableResolver”). Si consiglia vivamente agli sviluppatori di applicazioni di posizionare bean gestiti indicati dalle espressioni di collegamento dei componenti in ambito “richiesta”. Questo perché posizionarlo in ambito di sessione o applicazione richiederebbe la sicurezza del thread, poiché le istanze di UIComponent dipendono dall’esecuzione all’interno di un singolo thread. Vi sono anche impatti potenzialmente negativi sulla gestione della memoria quando si posiziona un bind del componente in ambito “sessione”.

    In caso contrario, le istanze dei componenti vengono condivise tra più richieste, con possibili errori di ” ID componente duplicato ” e comportamenti “bizzarri” perché i validatori, i convertitori e gli ascoltatori dichiarati nella vista vengono riapplicati all’istanza del componente esistente dalle richieste precedenti. I sintomi sono chiari: vengono eseguiti più volte, una volta di più con ogni richiesta nello stesso ambito in cui il componente è stato associato.

    E, sotto carico pesante (cioè quando più richieste HTTP diverse (thread) accedono e manipolano la stessa istanza di componente contemporaneamente), è ansible che prima o poi si verifichi un arresto anomalo dell’applicazione, ad esempio, il thread bloccato su UIComponent.popComponentFromEL o Java Threads con il 100% di utilizzo della CPU utilizzando UIDataAdaptorBase e la sua HashMap interna , o anche qualche “strano” IndexOutOfBoundsException o ConcurrentModificationException provenienti direttamente dal codice sorgente di implementazione JSF mentre JSF è impegnato a salvare o ripristinare lo stato di visualizzazione (cioè la traccia dello stack indica saveState() o restoreState() metodi e simili).

    L’utilizzo del binding su una proprietà bean è una ctriggers pratica

    Indipendentemente, usando l’ binding questo modo, l’associazione di un’istanza di un intero componente a una proprietà bean, anche su un bean con scope richiesta, si trova in JSF 2.xa caso d’uso piuttosto raro e generalmente non è la migliore pratica. Indica un odore di design. Normalmente si dichiarano i componenti nella vista e si styleClass loro attributi di runtime come value , e forse altri come styleClass , disabled , rendered , ecc. styleClass normali proprietà dei bean. Quindi, devi semplicemente manipolare esattamente la proprietà del bean che desideri invece di afferrare l’intero componente e chiamare il metodo setter associato all’attributo.

    Nei casi in cui un componente deve essere “costruito dynamicmente” in base a un modello statico, è meglio utilizzare tag di generazione del tempo di visualizzazione come JSTL , se necessario in un file di tag , invece di createComponent() , new SomeComponent() , getChildren().add() e cosa no. Vedi anche Come refettare lo snippet del vecchio JSP con un equivalente JSF?

    Oppure, se un componente deve essere “reso dynamicmente” in base a un modello dinamico, utilizzare solo un componente iteratore ( , , ecc.). Vedi anche Come aggiungere dynamicmente componenti JSF .

    I componenti compositi sono una storia completamente diversa. È del tutto legittimo bind i componenti all’interno di una al componente di supporto (ovvero il componente identificato da . Vedere anche ao Split java.util.Date su due h: campi di inputText che rappresentano ora e minuto con f: convertDateTime e Come implementare un elenco dinamico con un componente composito JSF 2.0?

    Utilizzare solo l’ binding nell’ambito locale

    Tuttavia, a volte ti piacerebbe conoscere lo stato di un componente diverso all’interno di un particolare componente, più spesso in casi d’uso relativi alla convalida azione / valore dipendente. Per questo, l’attributo di binding può essere usato, ma non in combinazione con una proprietà bean. Si può semplicemente specificare un nome di variabile univoco dell’oscilloscopio locale nell’attributo di binding come binding="#{foo}" e il componente è durante la risposta di rendering altrove nella stessa vista direttamente come riferimento UIComponent disponibile da #{foo} . Qui ci sono diverse domande correlate in cui tale soluzione è stata utilizzata nella risposta:

    • Convalida l’input come richiesto solo se viene premuto un determinato pulsante di comando
    • Come eseguire il rendering di un componente solo se non viene eseguito il rendering di un altro componente?
    • Indice di riga DataTable JSF 2 senza dataModel
    • Primefaces dependent selectOneMenu e required = “true”
    • Convalidare un gruppo di campi come richiesto quando almeno uno di essi è compilato
    • Come cambiare la class css per il campo di input e l’etichetta quando la validazione fallisce?
    • Ottenere componenti definiti da JSF con Javascript
    • Utilizzare un’espressione EL per passare un ID componente a un componente composito in JSF

      (e questo è solo dall’ultimo mese …)

    Guarda anche:

    • Come usare il binding di componenti in JSF giusto? (componente con ambito di richiesta nel bean con ambito di sessione)
    • Visualizza ambito: java.io.NotSerializableException: javax.faces.component.html.HtmlInputText
    • L’attributo di associazione causa l’ID di componente duplicato trovato nella vista

    ogni componente JSF si rilascia in HTML e ha il controllo completo su quale HTML produce. Ci sono molti trucchi che possono essere usati da JSF, e esattamente quale di questi trucchi sarà usato dipende dall’implementazione JSF che stai utilizzando.

    • Assicurati che ogni input abbia un nome univoco, in modo che quando il modulo viene nuovamente inviato all’albero dei componenti che lo ha reso, è facile dire dove ciascun componente può leggere la sua forma di valore.
    • Il componente JSF può generare javascript che invia nuovamente al serer, il javascript generato sa dove è associato anche ogni componente, perché è stato generato dal componente.
    • Per cose come hlink puoi includere informazioni di binding nella url come parametri di query o come parte dell’url stesso o come parametri di matrx. per esempio.

      http:..../somelink?componentId=123 consentirebbe a jsf di cercare nella struttura dei componenti per vedere che il collegamento 123 è stato cliccato. oppure potrebbe e htp:..../jsf;LinkId=123

    Il modo più semplice per rispondere a questa domanda è creare una pagina JSF con un solo link, quindi esaminare l’output html che produce. In questo modo saprai esattamente come ciò avviene usando la versione di JSF che stai utilizzando.