Zawieranie obiektu w Klasie służącej jako strumień TCP

0

Witam.

Chciałbym się dowiedzieć czy jest taka możliwość, aby zamieścić obiekt dowolnej klasy w innym obiekcie klasy, której obiekty mają służyć jako strumień TCP.
Spróbuje przedstawić to w kodzie:

class ObjectStream<V> implements Serializable{
        
        private int id=0;
        private V ob;

        ObjectStream(V o,int i){
            this.id=i;
            ob=o;
            
        }
        
        ObjectStream(V o){
            ob=o;
        }
        
        V getObject(){
            return ob;
        }
        
        int getid(){
            return id;
        }
        
    }

//a potem użycie:

obtabout.get(i).writeObject(new ObjectStream(v));

//obtabout jest tablicą obiektów ObjectOutputSream

Wiadomo że ten kod nie działa, pobrane obiekty zwracają wartość null, wydaję mi się że jest to wina referencji obiektu a nie jego przypisania. Można to w jakiś sposób zrobić ?

1

Z tego kodu bezpośrednio nie wynika, czy powinien działać czy nie.

W każdym razie, według dokumentacji klasy ObjectOutputStream:

Serialization does not write out the fields of any object that does not implement the java.io.Serializable interface.

Czyli musisz upewnić się, że w polu ob masz obiekty klas implementujących interfejs Serializable.

0

W tym problem że "ob" jest obiektem klasy implementującej Serializable i nie działa.

Dlatego pytam :>.

1

Sprawdź zatem czy poprawnie serializowane są właśnie te obiekty, np. obtabout.get(i).writeObject(v);

Jeśli tak to ustaw poprawny setter dla tego pola, i napraw getter. setOb() i getOb(). Bo ob masz prywatne.

0

Na obiektach wkładanych Serializacja przebiegła dobrze, testowałem to wcześniej.

static class Dane implements Serializable{
        String a;
        String b;
        
        Dane(String a1,String b1){
            a=a1;
            b=b1;
        }
        
        public String toString(){
            return "Dane: "+a+" "+b;
        }           
                
    }

//wysyłanie obiektu:

 Dane d = new Dane("debil","mistrz");
 c.sendObjTCP(d);

//zaś metoda sendObjTCP :

 public void sendObjTCP(Object v) {
      ....
                    for(int i=0;i<clients.size();i++)
                    obtabout.get(i).writeObject(new ObjectStream(v));
       ....
    }

//zaś przy odbiorze:

Dane a;
a=(Dane)c.getObjTCP(0);
 System.out.println(a);

//gdzie getObjTCP:

public Object getObjTCP(int id){
....
                Object ob = obtabin.get(id).readObject();
                ObjectStream stream = (ObjectStream)ob;
                return stream.getOb();
.....
 }

Gdy nie używałem ObjectStream to wysyłane bezpośrednio obiekty zostały pobrane i wyświetlone poprawne.
Zaś z tą klasą wyświetlenie ich zwraca wartość null.

1

Coś musiałeś namieszać. Zrobiłem mały teścik i śmiga jak należy:

Data.java:

import java.io.Serializable;

public class Data implements Serializable {

  private String a;
  private String b;

  public Data(String a, String b) {
    this.a = a;
    this.b = b;
  }

  @Override
  public String toString() {
    return "Data{" + "a=" + a + ", b=" + b + '}';
  }
  
}

ObjectWrapper.java:

import java.io.Serializable;

public class ObjectWrapper implements Serializable {

  private Object object;

  public ObjectWrapper(Object object) {
    this.object = object;
  }

  public Object getObject() {
    return object;
  }

  @Override
  public String toString() {
    return "ObjectWrapper{" + "object=" + object + '}';
  }
  
}

Test.java:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class Test {

  public static void main(String[] args) throws Exception {
    String fileName = "serialize-test.bin";
    
    Data test1 = new Data("Ala", "Kot");
    Data test2 = new Data("Foo", "Bar");
    ObjectWrapper ow = new ObjectWrapper(test2);
    
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(fileName));
    oos.writeObject(test1);
    oos.writeObject(ow);
    oos.close();
    
    System.out.println("Zapis - dane: "+ test1 +"; wrapper: "+ ow);
    
    ObjectInputStream iis = new ObjectInputStream(new FileInputStream(fileName));
    Data readTest1 = (Data) iis.readObject();
    ObjectWrapper readOw = (ObjectWrapper) iis.readObject();
    iis.close();
    
    System.out.println("Odczyt - dane: "+ readTest1 +"; wrapper: "+ readOw);
  }
}

W wyniku dostaje:

Zapis - dane: Data{a=Ala, b=Kot}; wrapper: ObjectWrapper{object=Data{a=Foo, b=Bar}}
Odczyt - dane: Data{a=Ala, b=Kot}; wrapper: ObjectWrapper{object=Data{a=Foo, b=Bar}}

Edit:
Aha, do serializacji - nawet dla pól prywatnych - settery i gettery nie są konieczne.

I druga kwestia - musisz pamiętać żeby po drugiej stronie (bo przecież wysyłasz po sieci) mieć definicje wszystkich przesyłanych klas. Czyli w najprostszym przypadku ten sam jar po obu stronach.

0

Pisząc ten skrypt zanim wypisywać logi to je zapisywałem do String'u, po tym jak przeczytałem twój post od razu je sprawdziłem i wszystko jasne !!

Klasa ObjectStream znajdowała się wewnatrz innej klasy, która zaś nie implementowała Serializable i to był cały błąd XD.

Dzięki za pomoc, masz łapki i NAJ :D.

1 użytkowników online, w tym zalogowanych: 0, gości: 1