In questo articolo si vede come sia possibile inviare l'istanza di un oggetto Java al server utilizzando il protocollo HTTP.
Introduzione
Capita spesso, nella realizzazione di applet, di avere la necessità di memorizzare sul server degli oggetti presenti nell'applet. Ci sono principalmente due buone ragioni per fare ciò:
- è necessario memorizzare lo stato dell'applet sul server per poi recuperarlo in un secondo momento
- si vuole inviare un oggetto al server su cui verrà passato, in qualche modo, ad una
JVM che lo utilizzerà
La prima soluzione che viene in mente quando si pone questo problema è quella di usare un Socket TCP/IP in cui l'applet serializza gli oggetti necessari, che vengono quindi ricostruiti sul server.
Questa soluzione, seppur percorribile, risulta spesso impraticabile a causa dei firewall che cercano di controllare le connessioni da e verso una rete locale. Diventa quindi necessario trovare un modo per aggirare questa restrizione tenendo conto che le connessioni HTTP sono le uniche su cui normalmente si può fare affidamento.
L'articolo mostra dapprima come inviare un oggetto Java da un'applet al server utilizzando una connessione dedicata e successivamente sostituisce questa connessione con una connessione HTTP standard.
Serializzazione di oggetti in un Socket TCP/IP
La prima soluzione si basa sull'apertura di un socket al server e sull'utilizzo di un ObjectOutputStream per serializzare l'oggetto, che deve implementare l'interfaccia java.io.Serializable, nel canale che viene poi ricostruito sul server utilizzando un ObjectInputStream.
Ovviamente sia il server che il client devono possedere la definizione della classe a cui appartiene l'oggetto inviato.
Il codice di invio è simile al seguente:
...
public void send(InetAddress s, int p, Serializable obj)
throws IOException {
Socket s = new Socket(s, p);
ObjectOutputStream out;
out = new ObjectOutputStream(s.getOutputStream());
out.writeObject(obj);
s.close();
}
...
Sul server ci sarà un thread responsabile della ricezione degli oggetti che vengono memorizzati in un buffer in attesa che qualcuno li recuperi con il metodo receive():
...
private Vector buffer;
...
public void run() {
ServerSocket ss = new ServerSocket(PORT);
while (acceptClients) {
Socket s = ss.accept();
ObjectInputStream in;
in = new ObjectInputStream(s.getInputStream());
buffer.addElement(in.readObject());
s.close();
}
}
...
public Object receive() {
if (buffer.size() == 0)
return null;
Object ret = buffer.elementAt(0);
buffer.removeElementAt(0);
return ret;
}
Il metodo run() è eseguito da un thread che accetta le connessioni in ingresso. Gli oggetti ricevuti vengono memorizzati in un vettore che viene consultato quando viene invocato il metodo receive().
Conclusioni
Il valore dell'articolo sta nel mostrare il passaggio concettuale da una soluzione diretta ma fragile rispetto all'infrastruttura, il socket puro, a una soluzione più realistica per il web, fondata su HTTP.
L'obiettivo non è solo trasmettere oggetti Java, ma farlo in un contesto reale in cui i firewall obbligano a ragionare sui protocolli effettivamente disponibili.