Visualizzazione dei risultati da 1 a 10 su 10
  1. #1

    [JAVA] Problema serializzazione

    Salve a tutti, innanzitutto spero di non aver sbagliato sezione, in tal caso chiedo scusa.
    Passando al mio problema, esso riguarda la serializzazione di java, mi spiego meglio: devo inviare tramite socket degli oggetti Answer (implementa Serializzable e contiene un int ID,una String Answer e Object Content), più precisamente ho un problema sul content quando deve essere un oggetto ListMatch (che implementa Serializzable ed estende ArrayList<Match> , dove Match implementa anch'esso Serializzable e contiene per semplicità una Stringa che è il nome della partita).
    Il server invia questa Answer ma alla ricezione il client nel content dell'Answer, ricevuta correttamente, si ritrova solo un Match e non una ListMatch. Quale potrebbe essere il problema?
    Grazie in anticipo.

  2. #2
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,326
    Ciao.
    Java ha una sezione dedicata, dove sposerò la discussione.
    Per capire dove possa essere il problema dovresti postare il codice, altrimenti non ti si può dire nulla, non potendo visionarlo.

    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  3. #3
    Ciao scusa se ho dovuto far spostare la discussione . Posto i pezzi di codice più importanti:
    Lato Server (Thread):

    codice:
         public void run()
         {
              
             try {
                 //ottiene gli stream di I/O dalla socket
                 ois = new ObjectInputStream(socket.getInputStream());
                 oos = new ObjectOutputStream(socket.getOutputStream());
                 cont=0;
                 while(!socket.isClosed()){
                         cont++;
                           // legge la richiesta
                         richiesta = (Request)ois.readObject();
    //                     System.out.println("SERVER: Ho ricevuto la richiesta n°"+cont+", REQUEST: "+richiesta.getRequest());                         this.sleep(5);
                        manageRequest(richiesta,oos);
                 }
                    
                 ois.close();
                 oos.close();
                 socket.close();
                    
                } catch (Exception e) {
                    System.out.println(e.getMessage());
                }    
         } // run()
         
        
        
        private void manageRequest(final Request request,final ObjectOutputStream oos) {
                    switch (request.getRequest()) {
                        case "search":
                        {
                            System.out.println("SERVER THREAD RICEVUTO SEARCH.");
                            ListMatch temp=server.getMatchs();
                            if(temp==null)
                                temp=m; 
                            try {
                                System.out.println("SERVER: Size---> "+temp.size());
                                Answer answerTemp=new Answer(LIST,temp,cont);
                                oos.writeObject(answerTemp);
                                oos.flush();
                                //System.out.println("HO INVIATO la risposta "+cont+" la size list è "+((ListMatch)answer.getContent()).size());
                            } catch (IOException e) {
                                System.out.println("SERVER THREAD, ERRORE SCRITTURA LISTA PARTITE, SEARCH: "+e.getMessage());
                            }
                            break;
                        }
                    }

    Lato CLIENT (Thread):

    codice:
                   public void run() {
                try {
                    if(client.getInputStream()==null||client.getOutputStream()==null)
                        System.out.println("ERRORE MANAGER COMUNICATION 1");
                    oos = new ObjectOutputStream(client.getOutputStream());
                    ois = new ObjectInputStream(client.getInputStream());
                } catch (IOException e1) {
                    System.out.println(e1.getMessage());
                }
                try {
                    if(ois==null||oos==null)
                        System.out.println("ERRORE MANAGER COMUNICATION 2");
                    System.out.println("Client ready.\n");
                    
                    while (!(requestUser.getRequest().equals("close"))) {
                            oos.writeObject(requestUser);
                            oos.flush();
                            try {
                                Thread.sleep(20);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            // legge la richiesta
                            Answer temp=(Answer)ois.readObject();
                            ListMatch contentList=(ListMatch)temp.getContent();
                            System.out.println("ID:"+temp.getId()+" ANS:"+temp.getAnswer()+" CONT:"+contentList.toString());
                            String content=temp.getAnswer();
                            switch (content) {
                                case "list":
                                    System.out.println("CLIENT THREAD: LA RISPOSTA DEL SERVER CON ID:"+temp.getId()+"E LA SIZE E' "+((ListMatch)temp.getContent()).size());
                                    c.setAnswer(temp);
                                    requestUser=c.getRequest();
                                    break;
                                case "ok":
                                    break;
                                default:
                                    requestUser=new Request("close", null);
                                    System.out.println("CLIENT THREAD: STO CHIUDENDO LA CONNESSIONE");
                                    break;
                            }
                            
                    }
                    oos.writeObject(requestUser);
                    oos.flush();
                    
                    ois.close();
                    oos.close();
                    client.close();
                } catch (IOException | ClassNotFoundException e) {
                    System.out.println(e.getMessage());
                }
        }

    La classe ListMatch estende ArrayList<Match> ed implementa Serializzable
    La classe Match per semplicità ora è composta solo da una String che rappresenta il nome della partita
    La classe Answer (Request è simile) contiene questi parametri con relativi get e set:


    codice:
                   public String answer;
    private int id;
    private Object content;
    Ultima modifica di LeleFT; 12-01-2015 a 13:39 Motivo: Aggiunti i tag CODE

  4. #4
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,326
    Posta la classe Answer.

    A parte qualche spezzone di cui non ho capito il senso (tipo quello sleep da 20 ms tra l'invio della richiesta e la lettura della risposta nel client) alcune cose non chiare (cosa sono, rispettivamente, "m" nel server e "c" nel client?) e un punto non molto convincente (cosa accadrebbe se per qualche recondita ragione non si riuscissero ad aprire gli stream di I/O della socket lato client?), il codice che hai postato non mi sembra contenere errori evidenti (casomai lo rileggo con più calma dopo).

    L'unica cosa che rimane da capire, quindi, è proprio come lavora la classe Answer... dici che estende ArrayList ed implementa Serializable; ArrayList implementa già di suo Serializable, quindi qualsiasi sua sottoclasse la implementa di default per ereditarietà. Rimane da capire cosa venga fatto nel costruttore di tale classe.

    Sarebbe anche interessante vedere un po' delle stampe che vengono prodotte in esecuzione. E, ancor più interessante, sarebbe non ammazzare le eccezioni: in caso di eccezione tu fai stampare il getMessage(); non è sufficiente: fai stampare lo stackTrace(), così se accade qualcosa hai l'intera situazione delle chiamate stampata a video.


    Ciao.
    Ultima modifica di LeleFT; 12-01-2015 a 14:24
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  5. #5
    CLASSE LIST MATCH:
    codice:
     
    public class ListMatch extends ArrayList<Match>{
        private static final long serialVersionUID = 5559629197069790923L;
        public ListMatch(){
            super();
        }
        public boolean add(Match o){
            if(super.add(o))
                return true;
            return false;
        }
        public int size(){
            return super.size();
        }
        public Match get(int index){
            return super.get(index);
        }
    CLASSE ANSWER:

    codice:
    public class Answer implements java.io.Serializable
    {
            private static final long serialVersionUID = 6283306953381426204L;
            public String answer;
    	private int id;
    	 private Object content;
    	 public Answer(String answer, Object content, int id)
    	 { 
    		 this.answer = answer; 
    		 this.id=id;
    		 this.content=content;
    	 } 
    	 public void setObject(Answer temp){
    		 this.answer=temp.getAnswer();
    		 this.id=temp.getId();
    		 this.content=temp.getContent();
    	 }
    	 public int getId(){
    		 return id;
    	 }
    	 public Object getContent(){
    		 return content;
    	 }
    	 public String getAnswer(){
    		 return answer;
    	 }
    }
    Nel server m è un oggetto ListMatch vuoto che viene utilizzato nel caso in cui la lista di match è null, potrebbe essere una cosa superflua, cosi come la sleep sono prove che ho fatto. Perdonatemi ma sto cercando di imparare è la prima volta che faccio queste cose .
    Nel client thread, c è l'oggetto Client che lo avvia e che contiene dei parametri condivisi, resi persistenti tramite politiche di lock, al qual il client thread accede(e modifica).

    Ecco delle stampe:
    -----------------------------CLIENT---------------------------
    CLIENT THREAD: LA RISPOSTA DEL SERVER CON ID:154 E LA SIZE E' 1
    ID:154 ANS:list CONT:[Match@73e7287a]

    HO RICEVUTO LA RISPOSTA 154 la size è 1
    CLIENT THREAD: LA RISPOSTA DEL SERVER CON ID:155 E LA SIZE E' 1
    ID:155 ANS:list CONT:[Match@73e7287a]

    HO RICEVUTO LA RISPOSTA 155 la size è 1

    "Continuano sempre cosi, varia solo l'id (questo mi fa capire che i messaggi arrivano correttamente).
    La cosa strana è il content, ovvero CONT che è sempre uguale."
    -----------------------------------------------------------------
    ----------------------------SERVER----------------------------
    SERVER THREAD: RICEVUTO SEARCH.
    SERVER: Size---> 154
    SERVER THREAD RICEVUTO SEARCH.
    SERVER: Size---> 155
    -----------------------------------------------------------------
    Nel server la size corrisponde alla size sul server della lista delle partite.

    Grazie per la disponibilità

  6. #6
    Non c'è nessuno che può aiutarmi?

  7. #7
    Inutile dire che quel codice e veramente brutto da vedere, ma non ho capito esattamente cos'è che non ti torna.
    é per caso il fatto che con questo :
    System.out.println("ID:"+temp.getId()+" ANS:"+temp.getAnswer()+" CONT:"+contentList.toString());

    Ti viene stampato
    [Match@73e7287a] e non per caso ListMatch[....] ?

  8. #8
    Cosa c'è di brutto nel codice a parte le cose che mi sono state fatte già notare?Facendo prove ed essendo agli inizi soprattutto con la programmazione in rete penso sia normale .
    Comunque no non è quello il problema, manca la ridefinizione del toString. Il problema è un problema legato alla serializzazione, semplicemente il client riceve correttamente la lista di partite solo alla prima richiesta fatta al server, nelle successive esso riceve si i messaggi correttamente ma con la lista non aggiornata. Mi spiego meglio facendo un esempio:

    1)Il client chiede la lista
    2)Il server riceve la richiesta, crea un oggetto Answer con il tipo di risposta, ovvero list, la lista vera e propria e un id, in questo caso 1,(per semplicità ipotiziamo che la lista abbia solo una partita).Infine invia l'oggetto answer.
    3)Il client riceve l'oggetto Answer e lo deserializza correttamente, ovvero id=1, lista contenente solo una partita.
    4)Il client va a dormire per qualche millisecondo e rieffettua la richiesta per la lista di partite.
    5)Il server riceve la richiesta ed effettua lo stesso procedimento del punto 2.Stavolta ID=2, lista partita con 5 Parite.
    6)Qui sorge il problema, il client riceve l'oggetto Answer, lo deserializza, ottenendo l'oggetto con id=2(GIUSTO), tipo=list(GIUSTO), lista con una sola partita ovvero quella della prima richiesta(SBAGLIATO, doveva contenere le 5 partite).

  9. #9
    Si ma al server chi gli dice di aggiungere una partita ?

  10. #10
    Per semplicità ad ogni richiesta della lista da parte del client viene aggiunta una nuova partita.

Tag per questa discussione

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.