[英]Sending object through TCP socket - ClassNotFoundException
我有兩個簡單的應用程序:客戶端和服務器。 客戶端加密(簡單 AES)自定義對象並通過 TCP 套接字將其作為字節發送到服務器。 服務器解密這些字節並調用重新創建此對象的方法,如下所示:
private static Object getObjectFromBytes(byte[] credentials) throws IOException, ClassNotFoundException{
ByteArrayInputStream bis = new ByteArrayInputStream(credentials);
ObjectInput in = null;
Object credentialsObj = null;
try {
in = new ObjectInputStream(bis);
credentialsObj = in.readObject();
} finally {
bis.close();
in.close();
}
return credentialsObj;
}
在客戶端,當我加密這個對象時,它的類型是mds.hm5.client.ITU_Credentials
。 在服務器端,當我解密它並轉換回對象時,它應該是mds.hm5.tokenservice.ITU_Credentials
。 相反,我收到以下異常:
java.lang.ClassNotFoundException: mds.hm5.client.ITU_Credentials
他正在通過舊的類路徑尋找這個對象。 為什么會發生這種情況,我該如何解決?
附加信息:
這是我在客戶端將此對象轉換為字節數組的方法:
private static byte[] getBytesFromObject(Object credentials) throws IOException{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutput out = null;
byte[] newBytes = null;
try {
out = new ObjectOutputStream(bos);
out.writeObject(credentials);
newBytes = bos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
} finally {
out.close();
bos.close();
}
return newBytes;
}
我使用泛型類型Object
的原因是因為我將使用這些方法來轉換/加密/解密多種類型。 這是正確的方法嗎?
在客戶端,當我加密這個對象時,它的類型是 mds.hm5.client.ITU_Credentials。
這就是序列化流中的內容。
在服務器端,當我解密它並轉換回對象時,它應該是 mds.hm5.tokenservice.ITU_Credentials。
不,不應該。 它應該和你連載時一樣[除非你采取了某些神奇的步驟,而這顯然是你沒有的。 沒有這些神奇的步驟,就沒有魔法,也沒有什么可以將mds.hm5.client.ITU_Credentials
與mds.hm5.tokenservice.ITU_Credentials
連接mds.hm5.client.ITU_Credentials
]。 您有兩個具有相同名稱和不同包的不同類,每個位置一個。 他們不一樣。
他正在通過舊的類路徑尋找這個對象。
您對 CLASSPATH 和包名感到困惑。 它們不是一回事。 它正在通過它的實際包名稱尋找這個對象。 它還能做什么?
對象輸出流不會序列化類本身,而只會序列化它的狀態(字段值)。 接收器需要類路徑上的類文件。
也可以轉課。 您必須找到(或編寫)一個可以從您的連接加載類的類加載器。 如果您有類文件的 URL,那么您可以使用 URLClassloader。 然后您不必將該類添加到您的類路徑中。
您的客戶端需要在其類路徑中包含定義對象的 .class 文件。 您正在做的是序列化/反序列化實例,而不是類。
晚了,但它可能對將來的某人有用:我想發送一個對象Message,其包是客戶端的實體,但在服務器端,此Message類未嵌套在實體包中,因此拋出此異常. 這可能很愚蠢,但我花了很多時間弄清楚這一點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.