PDA

View Full Version : [Java Servlet] Pagina pasticciata quando aperta in contemporanea


Corvo80
24-03-2006, 17:53
Il problema è questo: sto sviluppando un'applicazione Server-Oriented per una rete intranet: essenzialmente più terminali devono collegarsi contemporaneamente al server (Apache Tomcat) tramite collegamento wireless; il server distingue le varie sessioni e, di conseguenza, non dovrebbero esserci problemi all'apertura contemporanea della servlet da parte di più terminali...

Ciò, infatti, è vero per alcune di esse (l'applicativo è sviluppato su più pagine/servlet tra esse collegate) ma nell'apertura di una data servlet (particolarmente complessa e dal caricamento lungo), viene fuori un bel pasticcio: a volte da un terminale viene stampata una doppia pagina (in cascata), mentre dall'altro pagina vuota (o parzialmente stampata); altre volte da una parte mi dà errore; altre volte ancora entrambe le pagine vengono visualizzate con frammenti di codice in bella vista tra un campo testo e un'altro...

Mi verrebbe quasi da pensare che sia un problema del Tomcat e non del codice... ma spero proprio di no!

La mia speranza è che qualcuno di voi sia incappato nel mio stesso problema e che mi spieghi come risolverlo. Grazie.

pinok
24-03-2006, 18:13
La servlet non dovrebbe mai essere troppo grande o particolarmente complessa.
Hai già provato a spostare fuori il codice "pesante" e a richiamarlo dalla servlet, in modo da attivare lo stream di output quando cominciano ad arrivare i dati dell'elaborazione e non durante ?

Corvo80
25-03-2006, 11:27
La servlet non dovrebbe mai essere troppo grande o particolarmente complessa.
Hai già provato a spostare fuori il codice "pesante" e a richiamarlo dalla servlet, in modo da attivare lo stream di output quando cominciano ad arrivare i dati dell'elaborazione e non durante ?

Uhmmm... no, in effetti e se devo essere sincero non ho ben idea di come procedere. Un aiutino?

pinok
25-03-2006, 13:45
Uhmmm... no, in effetti e se devo essere sincero non ho ben idea di come procedere. Un aiutino?
Ti fai una classe che si occupa delle elaborazioni, meglio se messa in un package (=directory).
Poi nella servlet importi la classe, passi i parametri che servono all'elaborazione (mediante il costruttore o direttamente al metodo), invochi il metodo e recuperi il risultato (ad es. un vettore o uno stringbuffer se è una sequenza di istruzioni HTML).

Quindi apri lo stream di scrittura, ci riversi il codice HTML e chiudi lo stream, eventualmente invocandoci sopra un flush per pulirlo.

Corvo80
27-03-2006, 15:00
Mi sono appena reso conto di una grave inconsistenza del mio codice (la mia niubbaggine non smette mai di stupirmi). L'oggetto PrintWriter che uso per lo streaming di output l'ho dichiarato fuori dai metodi (i quali non sono synchronized), con conseguente insorgere di problemi di concorrenza.

Se ho capito bene basta chiudere il codice concorrente in blocchi synchronized o dichiarare l'oggetto PrintWriter dentro e non fuori dei metodi, vero?

pinok
27-03-2006, 15:03
Se ho capito bene basta chiudere il codice concorrente in blocchi synchronized o dichiarare l'oggetto PrintWriter dentro e non fuori dei metodi, vero?
Potrebbe bastare.
Provare, grazie al cut & paste, costa poca fatica ;) quindi prova con una servlet e se funziona fallo per le altre.

Il suggerimento di organizzare meglio il codice resta comunque valido, se non altro per facilità di gestione e riusabilità del codice ;)

Corvo80
27-03-2006, 15:19
Come sempre hai ragione. :D

Grazie dell'aiuto, se avrò altri problemi tornerò a perseguitarti!!! :Prrr:

pinok
27-03-2006, 15:41
Come sempre hai ragione. :D

Grazie dell'aiuto, se avrò altri problemi tornerò a perseguitarti!!! :Prrr:
:doh:
Scherzo, sono qua...

Corvo80
27-03-2006, 17:33
Neanche a farlo apposta ho subito un altro consiglio da chiederti/vi.

Sto riprogettando il codice rendendolo più modulare e più elegante e mi è giunto un dilemma:

siccome gli elementi dell'interfaccia grafica (nomi delle label, dimensioni dei campi testo, etc...) delle varie servlet vengono letti da database tramite interrogazioni SQL restituite come oggetti ResultSet, l'idea è quella di eseguire la query alla prima apertura della servlet ( dal metodo init() ) e clonarne il risultato ogni volta che una nuova sessione viene creata.

Il problema è che gli oggetti ResultSet non sono clonabili, a quanto pare. Come posso fare?

pinok
27-03-2006, 21:07
Cosa intendi per clonare le resultSet?
Se intendi dire salvarti gli oggetti per non interrogare di nuovo il DB, se sono pochi dati puoi metterli in una lista e poi in sessione, se sono tanti non ti conviene (appesantiscono la memoria).
Tutto sommato, se sono pochi, a recuperarli ogni volta non è che pesa molto...

Corvo80
27-03-2006, 21:31
Niente, volevo dire tramite il metodo clone() ma mi sono reso conto che c'è un errore concettuale di fondo: ResultSet non è una classe, è un interfaccia.

Uhmmm... che ne dici di una lista statica, lasciando perdere di copiarla ogni volta nelle variabili sessione? Coi ResultSet aveva un senso, poichè sono provvisti di un puntatore che utilizzavo per la costruzione della riga ma se parliamo di lista posso usare un puntatore per ogni sessione e un'unica lista...