View Full Version : [Google Web Toolkit] Riferimento a InputStream in client?
tylerdurden83
10-07-2011, 11:47
Ragazzi sto smanettando un po con GWT, ma mi sono bloccato sul seguente problema.
In pratica, una delle classi del modello, che implementa serializable e che viene ritornata ai client da delle servlet mediante rpc, ha il problema di avere al suo interno (nel costruttore) un riferimento alla classe InputStream, che mi pare di capire non avere un corrispettivo in javascript in modo da poter essere sostituita dal compilatore gwt quando va a generare i js delle classi java nel package client.
Come posso aggirare il problema secondo voi?
Grazie mille,
TD
tylerdurden83
10-07-2011, 14:40
Vediamo se ho capito bene.
Per ogni classe del modello, ad es ModelloA, creo una classe ModelloADTO, che ha get e set per le variabili d'istanza di ModelloA, ma non ha la "logica" di ModelloA, tipo che ne so "computeMaxValue(ModelloB)".
In ModelloA metto un metodo
public ModelloADTO getDTO(){...}
che mi restituisce un il DTO di ModelloA, e i servizi offerti dalle servlet impl sul server ritornano solo ModelloADTO e non ModelloA.
Poi il passaggio inverso però, perchè ho bisogno di creare dei ModelloA a partire da ModelloADTO. Quindi posso aggiungere un ulteriore costruttore a quelli presenti in ModelloA, tipo
public ModelloA(ModelloADTO madto){...}
e nelle servlet impl ricevo dai client ModelloADTO e lo trasformo in ModelloA?
Corretto?
Si, direi che è giusto. Praticamente nel DTO metti solo i dati che userai nel parte client (generalmente saranno solo i dati da visualizzare o poco altro).
Questo ha diversi vantaggi, ad esempio passi meno dati tra client e server (ricorda che si tratta di passaggio di dati su rete, può aver senso ottimizzare), risolvi problemi tipo il tuo, aggiungi un maggior disaccoppiamento tra servizi e presentazione.
L'unica pecca di questo approccio è, a mio parere, che sporchi il modello con riferimenti alla parte di presentazione (il dto, appunto). D'altronde se facessi il contrario, ovvero mettessi riferimenti a ModelloA in ModelloADTO, *credo* saresti punto a capo (ma a volte gwt è piuttosto tollerante, magari per un semplice riferimento in un costruttore potrebbe anche lasciar correre, ma ne dubito... purtroppo al momento non ho il necessario per provare).
Cmq sono le classiche pippe mentali dell'informatica, direi che nella pratica poi va più che bene ;)
Kralizek
11-07-2011, 14:15
crea un DTOzer in livello applicazione/presentazione
qualcosa come
public class DTOFactory
{
public ModelloADTO GetDTOForModelloA(ModelloA modello) { ... }
}
tylerdurden83
11-07-2011, 16:38
Praticamente nel DTO metti solo i dati che userai nel parte client (generalmente saranno solo i dati da visualizzare o poco altro)
Inizialmente avevo fatto così, ossia "esportare" solo le variabili d'istanza di ModelloA in ModelloADTO che vengono visualizzate in qualche modo.
Il problema è che così facendo poi non posso tornare indietro da ModelloADTO a ModelloA.
Faccio un esempio al volo:
public class DAOModelloB{
public static ModelloB GetXXX(ModelloA a){...}
}
dove ModelloA e ModelloB sono due oggetti del mio modello "di base", e DAOModelloB ha un metodo che restituisce un ModelloB a partire da un ModelloA in input.
Ora, andando a scrivere una servlet per esporre tale servizio via rpc (tralasciando i tre pezzi, interfaccia e interfaccia async sul client, impl sul server), avrò una cosa del tipo:
public class ... {
public ModelloBDTO getXXX(ModelloADTO a){...}
}
Nella Impl, quindi lato server, dove posso usare le versioni NON DTO, posso trasformare ModelloADTO in ModelloA, posso chiamare DAOModelloB.GetXXX(ModelloA), trasformare il ModelloB restituito in ModelloBDTO, e restituire quest'ultimo al client.
Il problema di trasformare ModelloADTO in ModelloA in questo metodo mi obbliga a far si che ModelloADTO si sia portato appresso anche i dati non prettamente "da gui" del ModelloA da cui è stato generato, altrimenti andando a fare la trasformazione inversa ottengo un ModelloA mezzo vuoto.
In sostanza:
ModelloA1 ---> applico una funzione f ---> ModelloA1DTO ---> applico f-1 ---> ModelloA2,
con ModelloA1 != ModelloA2, nel caso in cui ModelloADTO non contenga ogni singola variabile di instanza di ModelloA.
Spero di essermi spiegato...
L'unica pecca di questo approccio è, a mio parere, che sporchi il modello con riferimenti alla parte di presentazione (il dto, appunto). D'altronde se facessi il contrario, ovvero mettessi riferimenti a ModelloA in ModelloADTO, *credo* saresti punto a capo
Concordo al 100%, e si, al contrario si incazza...
@Kralizek: non vorrei dire una fesseria, ma usando una factory sono costretto a dotare ModelloA di un get() pubblico per ogni variabile di instanza che deve trasferire in ModelloADTO, e questo non è del tutto accettabile. Usando un metodo ModelloADTO getDTO() definito dentro ModelloA posso non esportare all'esterno le variabili private di ModelloA ad esempio...
Generalmente sono pochi i dati veramente sensibili che identificano l'oggetto, con quelli è facile risalire all'oggetto base (chiaramente in linea generale, ora non conoscendolo non posso aiutarti sul tuo caso specifico). Quelli andranno tutti nel dto; a meno che, chiaramente, tu butti via l'oggetto base dopo aver creato il dto, non dovresti avere la necessità di "ricostruirlo", ma semplicemente ripescarlo e fargli le modifiche opportune.
Tant'è che spesso lo dovrai fare in ogni caso: pensando solo alle chiamate crud, ad esempio update, il dto tornerà al server con qualche dato modificato, e tu dovrai essere in grado di beccare il bean/record di partenza e modificarlo (spesso su db, o tramite hibernate, ecc.).
Ad esempio, supponi di avere una classe Persona con una valanga di campi; di questi te ne servono solo alcuni lato client. Lato server, avrai un'anagrafica, probabilmente un dao, che ti permette di recuperare una persona, dato, ad esempio, il codice fiscale. Anche se non ti serve lato client, tu inserisci il codice fiscale nel dto; quando ritorni al server il dto, con ad esempio la data di nascita cambiata, tu non hai bisogno di ricostruire la Persona originale; te la fai semplicemente tornare dall'anagrafica e la modifichi.
Sto pensando al caso più comune; se per qualche motivo non hai anagrafiche o non tieni in memoria gli oggetti base, allora probabilmente l'unico modo e portarsi nel dto tutti i dati necessari.
tylerdurden83
12-07-2011, 17:44
@Mesh89: tutto chiarissimo, ti seguo al 100%, ora devo solo cercare di ridurre al minimo gli oggetti da dover passare.
Ho un ultimo (ultime parole famose? ;) ) dubbio. Nella versione Swing il mio oggetto A che veniva visualizzato era anche un Observer di un oggetto B che elaborava dei dati. B ad esempio passava ad A a che punto dell'elaborazione era arrivato con delle notifiche mediante pattern Observer/Observable.
Ora che l'oggetto "GUI" è il DTO che viene visualizzato lato client, come faccio a far sì che quest'ultimo riceva degli update dall'elaboratore lato server? Da quello che vedo in giro, onSuccess (o onFailure) sono chiamati, per quanti in maniera asynch, solo al termine dell'elaborazione ed invio dal server al client, mentre io ho bisogno di update intermedi...
Purtroppo dall'"alto" della mia inesperienza, non ho mai usato Swing.
Se il pattern observer è ciò che immagino, dovrebbe esserci un'oggetto observed (server) che, quando succede qualcosa, invia delle notifiche all'oggetto observer (client), banalmente tenendo un riferimento dentro di se e chiamando un metodo dell'observer.
Questo non è possibile nel nostro caso, perché in un applicazione web un server non può chiaramente invocare metodi della parte client. L'unica cosa che mi viene in mente è quella di un timer lato client che effettui dei polling al server per conoscere lo stato dell'oggetto.
Ma ripeto, non ho esperienza in queste cose è potrei star dicendo boiate...
tylerdurden83
12-07-2011, 21:16
Io invece ho piu esperienza con swing che con il web, ma avevo capito che con tecnologie tipo ajax / servlet 3.0 / comet etc era possibile ottenere un effetto simil "notifiche push", invece di utilizzare attese attive / polling...
http://retkomma.wordpress.com/2009/08/05/server-to-client-notification-using-asp-net-and-comet-approach/
http://stackoverflow.com/questions/219868/client-notification-should-i-use-an-ajax-push-or-poll
Comunque si, pare che questo comet faccia al caso tuo..
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.