2011-09-27 66 views
1

我试图通过套接字连接发送一个自定义的对象。该类实现可串行化,但是当试图将对象写入套接字时,构造函数仍会抛出NotSerializableException。我会张贴以下相关的代码:通过套接字发送可序列化对象时发生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; 
    } 
} 

这是我的定制课程。现在我试图从服务器发送一个数组列表到客户端,但我会在后面的阶段添加更多信息。发送方法贴在我的服务器类下面是张贴如下:

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是im试图发送的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

类'Gesäll.Client'不可序列化。它需要整个serilizableArrayHolder类可序列化。 –

回答

5

其中可达通过serilizableArrayHolder所有类都必须Serializable包括你Client类。

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

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

+0

好吧,所有我试图完成的事情是将arrayList从服务器发送到客户端。为了澄清,我目前的设计是,当用户使用我的主应用程序连接到服务器时,服务器创建类Client的实例,并将“Client”实例添加到ArrayList。然后,这个数组列表将包含所有“在线”客户端的参考。至于现在,我的可serilizableArrayHolder只接受arraylist,但我的计划是使其通用接受其他对象以及 –

+0

为什么你发送ClientList给你的客户?你的客户是否必须相互沟通?如果他们这样做,他们应该做点对点或通过服务器? – palacsint

7

异常告诉你这个问题。您的Client类不可序列化。要序列化一个对象,它所引用的所有对象(等等,可传递)也需要可序列化。如果您不想将其序列化,则可以标记参考transient

+0

谢谢。我已经使客户端类可以被serilizable了,但是它仍然会抛出同样的错误。从我可以告诉ArrayList不可以serilizable,这可能会导致错误。我创建时试图创建我的ArrayList瞬态,但仍产生一个异常 –

+1

@JimmyGustafsson:'ArrayList'是'Serializable',请检查[javadoc](http://download.oracle.com/javase/6/docs/ API/JAVA/util的/ ArrayList.html)。发布你的'客户'类也是如此。 – palacsint

+2

@Jimmy Gustafsson如果你有相同的异常和消息,你没有部署该类的可序列化版本。如果您使用新消息得到相同的异常,则会命名另一个不可序列化的类。 – EJP

相关问题