java - 从ObjectInputStream读取一个对象(自定义)

标签 java client-server objectinputstream objectoutputstream

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

线程“main”中的异常 java.lang.ClassNotFoundException:Mining.FrequentPatternMiner 在 java.net.URLClassLoader$1.run(来源未知) 在 java.net.URLClassLoader$1.run(来源未知) 在 java.security.AccessController.doPrivileged( native 方法) 在 java.net.URLClassLoader.findClass(来源未知) 在 java.lang.ClassLoader.loadClass(来源未知) 在 sun.misc.Launcher$AppClassLoader.loadClass(来源未知) 在 java.lang.ClassLoader.loadClass(来源未知) 在 java.lang.Class.forName0( native 方法) 在 java.lang.Class.forName(来源未知) 在 java.io.ObjectInputStream.resolveClass(来源未知) 在 java.io.ObjectInputStream.readNonProxyDesc(来源未知) 在 java.io.ObjectInputStream.readClassDesc(来源未知) 在 java.io.ObjectInputStream.readOrdinaryObject(来源未知) 在 java.io.ObjectInputStream.readObject0(来源未知) 在 java.io.ObjectInputStream.readObject(来源未知) 在 JabberClient.main(JabberClient.java:81)

在服务器部分,我转换了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);

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

最佳答案

代码是正确的,但你的前提不正确。您说过,“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 实现/类,您可以尝试“远程处理”或“远程过程调用”(RPC)。这是一个高级主题,有很多库(和平台)提供此功能。他们基本上这样做:

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

关于java - 从ObjectInputStream读取一个对象(自定义),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24469862/

相关文章:

架构决策问题

java序列化随机访问,很奇怪的事情!

java - MySQL Connector/J - 将 Java 字符串映射到 MySQL INT

java - 使用 Liquibase 从远程数据库插入数据

java - 列表多态性

java - 延迟从 admob 加载横幅广告

c# - 如何从 Web 应用程序在多个客户端上远程执行程序?

java - 需要澄清LAN应用概念

java初始化流输入/输出变量

java - 为什么我的代码没有创建新文件?