简体   繁体   English

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

[英]read an Object(customized) from ObjectInputStream

So, I don't know why the Client part of my project give me this type of error 所以,我不知道为什么我的项目的“客户”部分会给我这种类型的错误

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)

In the Server part, I cast the FrequentPatternMiner variable and then i give it to the ObjectOutputStream 在服务器部分,我强制转换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);

In the Client part, i do this 在客户端部分,我这样做

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

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

How would I fix my code? 我该如何修正我的代码? Can you help me? 你能帮助我吗?

The problem you have is that FrequentPatternMiner is not on your classpath. 您遇到的问题是FrequentPatternMiner不在您的类路径中。

What you can do is ctrl+t on Eclipse and look for FrequentPatternMiner to know what is the jar containing this class. 您可以做的是在Eclipse上按ctrl+t并查找FrequentPatternMiner来知道包含该类的jar。 Then ensure that your project is referencing this class. 然后,确保您的项目正在引用此类。

If you are using maven you can use mvm dependency:tree goal to know if your project contain this jar. 如果您正在使用maven,则可以使用mvm dependency:tree目标来了解您的项目是否包含此jar。

The code is correct, but your premise isn't. 代码正确,但前提不正确。 You've said, that the class " FrequentPatternMiner must be unknown for the client". 您已经说过,类“ FrequentPatternMiner对于客户端来说必须是未知的”。 With that premise you can't serialize the class as you did, because serialization only transfers the data of the object and not it's implementation. 在这种前提下,您不能像以前那样对类进行序列化,因为序列化仅传输对象的数据, 而不传输其实现。 You might want to look into DataTransferObjects (which has to be known on both client and server) or use a simple array to transfer the object. 您可能想要研究DataTransferObjects(在客户端和服务器上都必须知道)或使用简单的数组来传输对象。

Example using a simple array as "DTO" 使用简单数组作为“ DTO”的示例

Server: 服务器:

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);

Client: 客户:

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]);

Further Idea 进一步的想法

If you don't want that FrequentPatternMiner implementation/class is known to the client, you can try "Remoting" or "Remote Procedure Calls" (RPC). 如果您不希望客户端知道FrequentPatternMiner实现/类,则可以尝试“远程”或“远程过程调用”(RPC)。 This is an advanced subject and there are a lot of libraries out there (and platforms) that provide this functionallity. 这是一门高级主题,并且有许多提供此功能的库(和平台)。 They do basically this: 他们基本上是这样做的:

  • You need an Interface for the Class on the client (like interface IPatternMiner { void doMine() } 您需要在客户端上为该类提供一个接口(例如interface IPatternMiner { void doMine() }
  • You connect server and client (depends on the library on how to do this) and obtain an instance of IPatternMiner 您连接服务器和客户端(取决于如何执行此操作的库),并获取IPatternMiner的实例
  • You call a method on the interface and the implementation gets executed on the server (with the parameters pased in from the client). 您在接口上调用方法,并且实现在服务器上执行(带有从客户端粘贴的参数)。 Note that file operations write on the file system on the server 请注意,文件操作写在服务器上的文件系统上

Casting to Object doesn't have any magical properties. 投射到对象没有任何神奇的属性。 Everything can be cast to Object. 一切都可以转换为对象。 It doesn't change the fact that what is written to the object stream is a FrequentPatternMiner, and if that class isn't available at the receiver, this exception will result. 不会改变写入对象流的是FrequentPatternMiner的事实,并且如果该类在接收方不可用,则会导致此异常。

Solution: deploy the class. 解决方案:部署类。

Similarly, casting an ObjectInputStream to ObjectInput accomplishes precisely nothing. 类似地,将ObjectInputStream强制转换为ObjectInput并不会完成任何操作。

You need to tyecast. 您需要播出。

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

Else how would the client know class of the Object that is being deserialized. 否则,客户端将如何知道要反序列化的Object的类。 Note it is not necessary to typecast just for using it in sysout . 注意,不必仅在sysout使用就进行类型转换。 It will print using Objects toString() method. 它将使用Objects的toString()方法进行打印。

Though your Exception says 虽然你的例外说

Exception in thread "main" java.lang.ClassNotFoundException

You need to add this class on the client side too. 您还需要在客户端添加此类。 Lastly check that serialVersionUID is same for the class in server and client. 最后检查服务器和客户端中的类的serialVersionUID是否相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM