Spedire oggetto istanziato in rete

di il
11 risposte

Spedire oggetto istanziato in rete

Ciao.
E' possibile in Java istanziare un oggetto su un server e spedirlo ad un client in modo tale da poterlo utilizzare ?

Grazie e buona serata

11 Risposte

  • Re: Spedire oggetto istanziato in rete

    Paolovox ha scritto:


    E' possibile in Java istanziare un oggetto su un server e spedirlo ad un client in modo tale da poterlo utilizzare ?
    È la "serializzazione degli oggetti" di Java. Però dovresti chiarire "chi" è il client (una applicazione Java standalone?)
    E dovresti anche dire perché ti serve.
  • Re: Spedire oggetto istanziato in rete

    Per client e server utilizzo Tomcat.
    Il client manda un messaggio HTTP al server con alcuni parametri, il server costruisce tramite un Builder l'oggetto, e lo dovrebbe spedire al client già istanziato.
    Il client possedendo la classe di quel tipo, poi potrà utilizzarlo come crede.
    Mi serve per concentrare la costruzione computazionalmente onerosa in un server, mentre il client con una sola richiesta HTTP avrà già il suo bell'oggetto precotto.
  • Re: Spedire oggetto istanziato in rete

    Paolovox ha scritto:


    Per client e server utilizzo Tomcat.
    Cioè c'è una webapp client e una server? Entrambe su Tomcat separati (e presumo su macchine proprio distinte)? Ok, nessun problema, è Java da entrambi i lati, dopotutto ..

    Paolovox ha scritto:


    Il client manda un messaggio HTTP al server con alcuni parametri, il server costruisce tramite un Builder l'oggetto, e lo dovrebbe spedire al client già istanziato.
    Il client possedendo la classe di quel tipo, poi potrà utilizzarlo come crede.
    Mi serve per concentrare la costruzione computazionalmente onerosa in un server, mentre il client con una sola richiesta HTTP avrà già il suo bell'oggetto precotto.
    Tecnicamente parlando, non ci sono problemi. Una request/response HTTP può benissimo contenere la sequenza di byte ottenuta dalla "serializzazione" degli oggetti di Java. Tieni solo presente che tale stream è appunto "binario", quindi lo svantaggio è che non è intelleggibile e quindi non lo potrai provare/verificare "a mano" con gli strumenti standard (estensioni di browser ecc...)
  • Re: Spedire oggetto istanziato in rete

    Finalmente ho capito cos'è e a cosa serve la serializzazione. Tutti i linguaggi OOP forniscono questo meccanismo?
    A volte se si vuole trasferire no un oggetto ma magari solo l'implementazione di una classe, non sarebbe meno costoso spedirlo come file di testo?

    Grazie mille e tra non molto spero di postare un pò di codice client, server che scambiano un piccolo oggetto serializzato.
  • Re: Spedire oggetto istanziato in rete

    Ho cominciato con un piccolissimo esempio. Però sbaglio qualcosa mi da "Server returned HTTP response code: 500". Tutte le impostazioni di Tomcat sono perfette, compreso il file xml. Qualche consiglio??

    === Object da serializzare ===
    
    public class Object implements Serializable{
    	private String s;
    	public Object(String s){
    		this.s = s;
    	}
    	public String getS(){return s;}
    }
    
    === Client ===
    
    public class Client {
    
    	private String urlParameters = "param1=prova";
    	private String url = "http://localhost:8080/Test/";
    	
    	private void sendPost() throws Exception{
    		
    	URL obj = new URL(url);	
    	HttpURLConnection con = (HttpURLConnection) obj.openConnection();
    	
    	con.setRequestMethod("POST");
    	
    	con.setDoInput(true);
    	con.setDoOutput(true);	
    
    	DataOutputStream wr = new DataOutputStream(con.getOutputStream());
    	wr.writeBytes(urlParameters);
    	
    	int responseCode = con.getResponseCode();
    	
    	ObjectInputStream in = new
    			ObjectInputStream(con.getInputStream());
    	
    	Object o = (Object) in.readObject();
    	
    	System.out.println(o.getS());
    
    	}
    	
    	public static void main(String[] args) throws Exception {
    		
    		Client c = new Client();
    		c.sendPost();	
    	}
    	
    }
    

    === Servlet ===
    
    public class Server extends HttpServlet {
        
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    		String parametro = request.getParameter("param1");
    		response.setContentType("application/x-java-serialized-object");
    		
    		response.getWriter().println("Parametro "+parametro);
    		Object obj = new Object(parametro);
            
            ObjectOutputStream o = new ObjectOutputStream(response.getOutputStream());
            o.writeObject(obj);
    
            o.close();
    		}
    
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	
    		doGet(request, response);
    	}
    }
    
  • Re: Spedire oggetto istanziato in rete

    Paolovox ha scritto:


    Ciao.
    E' possibile in Java istanziare un oggetto su un server e spedirlo ad un client in modo tale da poterlo utilizzare ?

    Grazie e buona serata
    Si, ma non conviene fare cosi'.
    O, almeno, ci sono tutta una serie di problematiche da affrontare che non sono per niente facili da risolvere.

    0.1) sei certo che da entrambe le parti c'e' la stessa versione di Java
    0.2) l'oggetto contiene SOLO valori semplici o anche puntatori ad altri oggetti? Una String NON E' un valore semplice
    0.3) l'oggetto deriva da Object o da qualche classe custom?
    0.4) lato client ci sono le stesse librerie del lato server?

    Ci sono diverse soluzioni possibili:

    1) uso di RMI: lato client usi un PROXY verso l'oggetto lato server
    2) uso di WebService: version cross-platform di RMI
    3) usi un meccanismo di serializzazione che non dipende da Java: JSON o XML
  • Re: Spedire oggetto istanziato in rete

    Paolovox ha scritto:


    
    		response.getWriter().println("Parametro "+parametro);
    		Object obj = new Object(parametro);
            
            ObjectOutputStream o = new ObjectOutputStream(response.getOutputStream());
            o.writeObject(obj);
    
            o.close();
    		}
    
    No, così no. Non va bene mixare getWriter() e getOutputStream() della response (in generale). E in ogni caso non va bene che prima dello stream "binario" della serializzazione ci metti davanti un qualcosa di testuale e arbitrario, perché lato client dovresti preoccuparti di interpretare e separare le due cose.
    Inoltre, sempre in generale, è bene che nella response ci sia il Content-Length appropriato. E questo vuol dire sapere a priori quanto è grande il body in byte. E significa che il ObjectOutputStream dovresti incatenarlo ad un ByteArrayOutputStream, poi sapendo la lunghezza scrivi il Content-Length e infine butti il contenuto di ByteArrayOutputStream sulla response.

    Così come hai fatto non ci siamo (e infine, non è buono mettere Object come nome di una tua classe).
  • Re: Spedire oggetto istanziato in rete

    migliorabile ha scritto:


    1) uso di RMI: lato client usi un PROXY verso l'oggetto lato server
    2) uso di WebService: version cross-platform di RMI
    3) usi un meccanismo di serializzazione che non dipende da Java: JSON o XML
    voto la (3)
  • Re: Spedire oggetto istanziato in rete

    Vi ringrazio per le risposte.
    Ho provato serializzando l'oggetto sul server con jdk8, mentre sul client avente jdk7 emergono i problemi che mi avete appena detto.
    In linea di massima come funziona il III approccio?
    E' facile da implementare?

    Grazie e buona serata.
  • Re: Spedire oggetto istanziato in rete

    Paolovox ha scritto:


    Ho provato serializzando l'oggetto sul server con jdk8, mentre sul client avente jdk7 emergono i problemi che mi avete appena detto.
    Salvo casi davvero particolari/strani, non ci sono problemi a livello di release di Java. La serializzazione degli oggetti usa un "protocollo" binario secondo una specifica ben precisa e questo NON cambia da una release di Java all'altra. È perfettamente possibile serializzare un oggettino con il JDK5 e poi deserializzarlo con il JDK8.

    È chiaro che sia chi serializza sia chi deserializza deve avere accesso alla STESSA definizione della classe. Non puoi pensare di avere sul client la classe serializzabile nel package "pippo" (es. pippo.MioOggetto ) e dall'altra parte nel package "pluto" (es. pluto.MioOggetto ). Così NON funziona.

    Esistono invece casi rognosi. Ad esempio NON serializzare mai delle inner-class (meno che mai le "anonymous" inner-class). Lì ci sono grane ben grosse.

    Paolovox ha scritto:


    In linea di massima come funziona il III approccio?
    Serve una libreria apposita (e chiaramente da comprendere bene) per la "(de)serializzazione" (termine qui usato in senso generale) di un oggetto in un formato XML o JSON.
    Per XML c'è già la API JAXB che è integrata nel framework da Java 6 in poi. Per JSON serve una libreria esterna apposita. Ma se è facile o meno dipende anche da quale approccio si intende usare per il binding dei dati e da quali altri framework (es. Spring? Jersey?) si sta usando.
  • Re: Spedire oggetto istanziato in rete

    Si giusto, perchè involontariamente ho utilizzato le espressioni lambda.
    Ora do un'occhiata alla API JAXB. Grazie mille.
Devi accedere o registrarti per scrivere nel forum
11 risposte