2012-12-03 8 views
13

Ricevo BusyConversationException durante la navigazione tra le pagine del mio progetto jsf. Questo accade principalmente se l'utente prova a navigare verso un'altra pagina durante una chiamata Ajax. Ciò accade anche quando l'utente fa clic su un collegamento subito dopo aver fatto clic su un altro collegamento senza attendere il caricamento della pagina.Come evitare BusyConversationException in jsf

Ad esempio, se l'utente fa clic su più di un collegamento generati tramite un codice simile a quello inferiore, otteniamo sicuramente questa eccezione. Un altro esempio è, diciamo che l'utente inserisce una query su un campo di testo e la nostra applicazione effettua una chiamata ajax per cercare questa query. Durante questa query, se l'utente fa clic su un pulsante per spostarsi su un'altra pagina, si verifica anche BusyConversationException.

<h:commandLink value="#{theProfile.profileName}" 
       title="#{theProfile.profileName}" 
       action="#{profileBean.aProfileSelected}"> 
       <f:setPropertyActionListener target="#{currentProfileWebBean.theProfile}" value="#{theProfile}"/> 
</h:commandLink> 

posso prendere questo tipo di eccezione in una classe ExceptionHandler che si estende classe ExceptionHandlerWrapper ma non posso salvare il mio stato attuale e il meglio che posso fare per questo caso è quello di reindirizzare alla pagina principale quando si verifica questa eccezione .

C'è qualche soluzione per evitare questo? Grazie in anticipo per le risposte e i commenti.

+0

Nota: 'BusyConversationException' non fa parte di JSF. Ho aggiunto il tag CDI. – BalusC

+0

Ci sono più chiamate Conversation.begin in corso? – LightGuard

+1

Anch'io sto avendo questo problema, se è rassicurante, e sono sorpreso da come _few_ persone sembrano averlo (basato su una ricerca sul web). Potrei finire per eliminare i miei fagioli con scope di conversazione e usare scope-scope e view-scope (con l'ambito di visualizzazione CDI fornito da Seam Faces). – Nick

risposta

2

Come accennato nelle altre risposte, questo accade se una richiesta AJAX è ancora in fase di elaborazione o se un evento ajax viene attivato prima del vero e proprio scatto sulla presentazione di commandLink o commandButton (ad esempio da un evento change su un campo di input).

Therfore è non è possibile per evitare BusyConversationExceptions con onclick="preventEventPropagation(event)";, dal momento che gli eventi AJAX non si attivano tramite la propagazione.

Il problema può essere facilmente evitato ascoltando l'esecuzione di richieste Ajax e il blocco dei sottotitoli fino a quando gli eventi Ajax non sono stati completati.

Il problema e la soluzione sono spiegati in modo più dettagliato in questo post del blog JSF2 AJAX/Submit conversation issue.

-1

L'ho visto occasionalmente anch'io. Sto iniziando a pensare che sia una buona idea di mettere qualche sforzo in accesso serializzazione le conversazioni:

  1. Evitare di propagare l'ID di conversazione (CID), quando non è necessario l'istanza di conversazione per la vista di destinazione. In particolare, i link/pulsanti di navigazione non correlati dovrebbero sopprimere il parametro cid (non hanno pensato esattamente a come farlo)
  2. Quando si avvia una richiesta che utilizza una conversazione attiva, disabilitare altri elementi dell'interfaccia utente che propagano la conversazione e potrebbero quindi causare concomitanza accesso. PrimeFaces o (ancora meglio) PrimeFaces Extensions blockUI componenti funzionano bene come un overlay traslucido, insieme a PrimeFaces p: ajaxStatus per mostrare lo stato occupato.
  3. Iniziare le conversazioni il più tardi possibile. Ciò ridurrà al minimo i casi in cui una conversazione di lunga durata verrà propagata.

Non penso che tutto questo sia una soluzione completa, però. Non appena il cid finisce nella barra degli indirizzi (che si verifica quando si esegue un post non ajax di un modulo quando una conversazione è attiva), si perde il controllo sui tempi di accesso a quella conversazione a causa di più schede/finestre, segnalibri, ecc

+0

Nel nostro caso abbiamo problemi quando terminare la conversazione e avviarne una nuova. Come posso iniziare una nuova conversazione ogni volta che l'utente fa clic su h: commandLink (il codice di esempio che ho dato nell'esempio)? Ho provato a terminare la conversazione nel bean di supporto tramite il setter # {currentProfileWebBean.theProfile}, ma vedo che il cid non sta cambiando affatto e PostConstructs non viene chiamato di nuovo? Quindi suppongo che la conversazione non finisca correttamente, ne hai idea? – cubbuk

+0

Qui è dove vorresti sopprimere il cid dall'essere inviato da 'h: commandLink' (che ancora non ho pensato a come realizzare, e potrebbe richiedere l'uso di' h: link' invece di 'h: commandLink'). In questo modo, non ci sarà una conversazione attiva per la richiesta e sarai libero di iniziarne una nuova. Si può pensare che la tecnica lasci una conversazione piuttosto che porre fine ad essa. – Brian

+0

Questo è esattamente ciò che mi piace imparare, usando h: commandLink per pubblicare alcuni parametri, ma non per postare cid in modo che una nuova conversazione possa essere avviata nella nuova pagina. Se uso h: link, allora ho bisogno di passare alcuni parametri (per questo esempio ho bisogno di passare "oggetto theProfile" come parametro) nel link url che non mi piace farlo. – cubbuk

0

ho trovato questo,

Indica che il contenitore ha rifiutato una richiesta perché una richiesta concorrente è associato allo stesso contesto di conversazione.

Il contenitore assicura che una conversazione di lunga durata possa essere associata al massimo una richiesta alla volta, bloccando o rifiutando richieste concorrenti. Se il contenitore rifiuta una richiesta, deve associare la richiesta con una nuova conversazione transitoria e generare un'eccezione di tipo BusyConversationException dalla fase di visualizzazione di ripristino del ciclo di vita JSF.

riferiscono here

-1

Ho anche affrontato lo stesso problema, quando ho usato per fare clic sul.

Ho letto in uno dei libri, busyConevrsation succede con quell'evento stanno accadendo due azioni, quindi hanno detto usare: onclick="preventEventPropagation(event)"; in commandLink per impedire la propagazione dell'evento per quel clic.Quindi ho usato lo stesso e funziona per me.

Così ora non sto ottenendo il BusyConversationException :)

+0

il metodo preventEventPropogration non è di aiuto in questo caso, ciò funzionerebbe solo se è stato attivato un altro lettore di clic. Tuttavia, in questo caso, una richiesta AJAX è già stata attivata e viene ancora elaborata o attivata prima dell'elaborazione del clic effettivo, ad esempio da un evento di modifica ajax. Per evitare tali problemi, è necessario ascoltare le richieste Ajax in sospeso e posticipare l'invio fino al termine dell'elaborazione della richiesta. Ho collegato un post sul blog nella mia risposta che spiega il problema e una possibile soluzione in modo più dettagliato. – dngfng