从ObjectInputStream中读取一个Object(自定义)

时间:2014-06-28 18:43:32

标签: java client-server objectinputstream objectoutputstream

所以,我不知道为什么我的项目的客户端部分给我这种类型的错误

Exception in thread "main" java.lang.ClassNotFoundException: Mining.FrequentPatternMiner at java.net.URLClassLoader$1.run(Unknown Source) at java.net.URLClassLoader$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Unknown Source) at java.io.ObjectInputStream.resolveClass(Unknown Source) at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source) at java.io.ObjectInputStream.readClassDesc(Unknown Source) at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) at java.io.ObjectInputStream.readObject0(Unknown Source) at java.io.ObjectInputStream.readObject(Unknown Source) at JabberClient.main(JabberClient.java:81)

在Server部分中,我转换了FrequentPatternMiner变量,然后将其提供给ObjectOutputStream

ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());

FrequentPatternMiner fpMiner=new FrequentPatternMiner(dataTarget, minsup);  
fpMiner.salva("FP_"+nameFile+"_minSup"+minsup+".dat");
System.out.println("Frequent Patterns \n"+fpMiner);

out.flush();
out.writeObject((Object)fpMiner);

在客户端部分,我这样做

ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());

Object fpMiner=in.readObject();
(((ObjectInput)in).readObject());
System.out.println(fpMiner);

我如何修复我的代码?你能救我吗?

4 个答案:

答案 0 :(得分:0)

您遇到的问题是FrequentPatternMiner不在您的类路径上。

您可以在Eclipse上执行ctrl+t并查找FrequentPatternMiner以了解包含此类的jar是什么。然后确保您的项目引用此类。

如果您正在使用maven,则可以使用mvm dependency:tree目标来了解您的项目是否包含此jar。

答案 1 :(得分:0)

代码是正确的,但你的前提是不正确的。您已经说过,对于客户来说,班级" FrequentPatternMiner必须是未知的"。有了这个前提,您就可以像对序一样对类进行序列化,因为序列化只传输对象的数据而它的实现。 您可能希望查看DataTransferObjects(必须在客户端和服务器上都知道)或使用简单数组来传输对象。

使用简单数组作为" DTO"

的示例

服务器:

ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());

// The following line assumes that dataTarget and minsup are types 
// that are serializable and known to the client
Object[] objArray = new Object[] { dataTarget, minsup };

out.flush();
out.writeObject(objArray);

客户端:

ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());

Object[] objArray = (Object[])in.readObject();
System.out.println(objArray);

// FrequentPatternMiner must still known to the client, if you need more than 
// the constructor arguments (like methods of the FrequentPatternMiner) Object.
FrequentPatternMiner fpMiner=new FrequentPatternMiner(objArray[0], objArray[1]);

进一步的想法

如果您不希望客户端知道FrequentPatternMiner实现/类,您可以尝试" Remoting"或"远程过程调用" (RPC)。这是一个高级主题,并且有很多库(和平台)提供这种功能。他们基本上这样做:

  • 您需要在客户端上使用类的接口(例如interface IPatternMiner { void doMine() }
  • 您连接服务器和客户端(取决于库如何执行此操作)并获取IPatternMiner
  • 的实例
  • 您在接口上调用方法,并在服务器上执行实现(从客户端输入参数)。请注意,文件操作在服务器上的文件系统上写入

答案 2 :(得分:0)

Casting to Object没有任何魔法属性。一切都可以转换为Object。它不会改变写入对象流的内容是FrequentPatternMiner的事实,如果该类在接收方不可用,则会导致此异常。

解决方案:部署课程。

类似地,将ObjectInputStream强制转换为ObjectInput只能完成任何操作。

答案 3 :(得分:-1)

你需要tyecast。

System.out.println((FrequentPatternMiner )fpMiner);

否则客户端如何知道正在反序列化的Object的类。请注意,没有必要仅仅在sysout中使用它进行类型转换。它将使用对象toString()方法打印。

虽然你的例外说

Exception in thread "main" java.lang.ClassNotFoundException

您还需要在客户端添加此类。最后检查服务器和客户端中的类serialVersionUID是否相同。