通过套接字发送可序列化对象时是否存在NotSerializableException?

时间:2011-09-27 16:02:25

标签: java sockets serialization objectoutputstream

我试图通过套接字连接发送自定义对象。该类实现了serializable,但是当我试图将对象写入套接字时,构造函数仍会抛出NotSerializableException。我将在下面发布相关代码:

public class serilizableArrayHolder implements Serializable {
   private ArrayList<Client> array= null;

   public serilizableArrayHolder(ArrayList<Client> array) {
       this.array=array;
   }

   public ArrayList<Client> getArray() {
     return array;
   }
}

这是我定制的课程。现在我试图从服务器发送一个arraylist到客户端,但我会在稍后阶段添加其他信息。 send方法发布在我的服务器类下面,发布如下:

public void sendData(Socket clientSocket){
    ObjectOutputStream out;

    try {
        serilizableArrayHolder temp = new serilizableArrayHolder(clientCollection);
        out = new ObjectOutputStream(clientSocket.getOutputStream());
        out.writeObject(temp);   <---This line generates the error.
        out.flush();
    } catch (IOException e) {
        e.printStackTrace();
    }

}

这是我从服务器发送的方法。 clientCollection是我尝试发送的arrayList。

整个客户端类:

public class Client implements Runnable, Serializable{
    public Thread thread = new Thread(this);
    private Socket s;
    private DataInputStream in;
    private DataOutputStream out;
    private ObjectOutputStream objOut;
    private ServerMain server=null;
    private String host=null;
    private Client c;
    private String userName;

public Client(Socket s, String host, ServerMain server) throws IOException{
    c=this;
    this.host=host;
    this.s=s;
    this.server=server;
    this.userName=userName;

    in= new DataInputStream(s.getInputStream());
    out=new DataOutputStream(s.getOutputStream());
    objOut=new ObjectOutputStream(s.getOutputStream());
    thread.start();
}

public String getClientInfo(){
    return host;
}
public String getUserName(){
    return userName;
}
public void send(String s){
    try {
        out.writeUTF(s);
        } 
    catch (IOException e){
    }
}

public void run() {

    while(true){
        try {
            String temp = in.readUTF();
            if(temp.equals("sendOnline")){
                sendOnline();
            }

            String tempHost=s.getInetAddress().getHostAddress();

            server.appendString(tempHost+" Skickade: "+temp+"\n");

            }
            catch (IOException e) {
                String str = s.getInetAddress().getHostName();
                server.clientDisconnect(str);
                break;
                }
        }

        try {
            s.close();
            } 
        catch (IOException e) {
                        }

}
public void sendOnline(){
    serilizableArrayHolder temp = new serilizableArrayHolder(server.getClients());
    try {
        objOut.writeObject(temp);
        objOut.flush();
    } catch (IOException e) {

        e.printStackTrace();
        }
            System.out.println("Metoden anropas");
}

}

新的堆栈跟踪:

java.io.NotSerializableException: java.io.DataInputStream
Metoden anropas
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1180)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1493)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
    at java.util.ArrayList.writeObject(ArrayList.java:710)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:962)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1493)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
    at Gesäll.Client.sendOnline(Client.java:83)
    at Gesäll.Client.run(Client.java:58)
    at java.lang.Thread.run(Thread.java:722)

2 个答案:

答案 0 :(得分:7)

该例外告诉您问题。您的Client课程不可序列化。要序列化对象,它引用的所有对象(以及传递等)也需要可序列化。如果您不希望序列化,可以标记引用transient

答案 1 :(得分:5)

所有可通过serilizableArrayHolder访问的课程必须为Serializable,包括您的Client课程。

您的Client班级包含SocketThreadDataInputStreamDataOutputStreamObjectOutputStream成员。它们都不是Serializable。这就是为什么你不能序列化Client类。这是另一个answer with the same topic

我认为您应该重新考虑您的设计并分享为什么要序列化这些对象。