Java 从ObjectInputStream读取对象(自定义)
所以,我不知道为什么我的项目的客户部分会给我这种类型的错误 线程“main”java.lang.ClassNotFoundException:Mining.FrequentPatternMiner中的异常 位于java.net.URLClassLoader$1.run(未知源) 位于java.net.URLClassLoader$1.run(未知源) 位于java.security.AccessController.doPrivileged(本机方法) 位于java.net.URLClassLoader.findClass(未知源) 位于java.lang.ClassLoader.loadClass(未知源) 位于sun.misc.Launcher$AppClassLoader.loadClass(未知源) 位于java.lang.ClassLoader.loadClass(未知源) 位于java.lang.Class.forName0(本机方法) 位于java.lang.Class.forName(未知源) 位于java.io.ObjectInputStream.resolveClass(未知源) 位于java.io.ObjectInputStream.readNonProxyDesc(未知源) 位于java.io.ObjectInputStream.readClassDesc(未知源) 位于java.io.ObjectInputStream.ReadOrderinaryObject(未知源) 位于java.io.ObjectInputStream.readObject0(未知源) 位于java.io.ObjectInputStream.readObject(未知源) 位于JabberClient.main(JabberClient.java:81) 在服务器部分,我强制转换FrequentPatternMiner变量,然后将其提供给ObjectOutputStreamJava 从ObjectInputStream读取对象(自定义),java,client-server,objectinputstream,objectoutputstream,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(本机方法) 位于java.net.URLClassLo
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);
如何修复代码?你能帮我吗?你得走了
System.out.println((FrequentPatternMiner )fpMiner);
否则,客户端将如何知道正在反序列化的对象的类。注意:仅在sysout
中使用它,不必进行类型转换。它将使用ObjectstoString()
方法打印
尽管你的特例说
Exception in thread "main" java.lang.ClassNotFoundException
您还需要在客户端添加这个类。最后检查服务器和客户端中的类的
serialVersionUID
是否相同 您遇到的问题是FrequentPatternMiner
不在您的类路径上
您可以在Eclipse上执行ctrl+t
,并查找FrequentPatternMiner以了解包含此类的jar是什么。然后确保您的项目正在引用此类
如果您使用的是maven,那么您可以使用
mvm dependency:tree
goal来了解您的项目是否包含此jar。代码是正确的,但前提不是正确的。您已经说过,类“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)。这是一门高级学科,有很多图书馆(和平台)提供这一功能。他们基本上是这样做的:
- 客户机上的类需要一个接口(如
接口IPatternMiner{void doMine()}
- 连接服务器和客户端(取决于库的操作方式)并获取
IPatternMiner的实例
- 在接口上调用一个方法,实现在服务器上执行(参数从客户端传入)
类似地,将ObjectInputStream强制转换为ObjectInput也不会产生任何效果。谢谢您的回答;)。对于客户端,FrequentPatternMiner类必须是未知的。我做了两个不同的项目,服务器和客户端。在服务器中,我放置了包含所有类的不同包,在客户端,我只放置了与服务器部分连接的部分
System.out.println((FrequentPatternMiner)fpMiner)代码>类型转换是完全不必要的。是的,但由于将调用对象toString()
,因此没有多大意义。OP不需要类型转换。该对象已属于该类。你关于Object.toString()的评论是毫无意义的。这不是100%正确的。如果FrequentPatternMiner实现了toString,那么不管强制转换是什么,都会调用它的toString实现。所以class Untitled{public static class Blob{public String toString(){return“mine”;}}}public static void main(String[]args){Blob b=new Blob();System.out.println(b);Object c=b;System.out.println(c);}}
返回相同的值。感谢您的回答,FrequentPatternMiner jar位于服务器项目中,客户端不应具有此属性class@user3786467给出错误的应用程序的类路径上肯定没有jar。谢谢你的回答,你能给我举个例子吗?我必须实现DataTransferObject,或者我只能在两个项目中导入?如何使用简单数组?是否有应在客户端上执行的FrequentPatternMiner
方法?然后,如果不让客户机知道jar中的类,就没有办法(读简单的方式)。您正在尝试反序列化它没有的类。我建议您创建一个包含服务器和客户端之间共享的所有对象的jar,并确保两端的jar版本相同。如何创建此jar?我将使用maven
,但您可以使用ant
或jar
命令,或者IDE中的一个插件。@这个对象是否具有神奇的属性?不部署类?认真地你的观点是什么?