2011-06-21 138 views
0

我在Android項目中有一個Packet類(com.lab.tracking.Packet)。我需要通過UDP將這個數據包發送到一個服務器,它具有該數據包類的完全副本(com.server.serverTracking.Packet)。將字節流轉換爲對象

android應用程序將數據包轉換爲字節流,然後將其發送到服務器。服務器正確接收的字節流,但是,當它試圖將其轉換爲一個包時,它拋出一個異常:

java.lang.ClassNotFoundException: com.lab.tracking.Packet 

我理解這一點。服務器試圖將此對象轉換爲com.lab.tracking.Packet,而不是com.server.serverTracking.Packet)。

從字節流對象轉換爲:

public static Object toObject(byte[] dataReceived) { 
    Object obj = null; 
    try { 
     ByteArrayInputStream bis = new ByteArrayInputStream(dataReceived); 
     ObjectInputStream ois = new ObjectInputStream(bis); 
     obj = ois.readObject(); 
    } catch (IOException ex) { 
     ex.printStackTrace(); 
    } catch (ClassNotFoundException ex) { 
     ex.printStackTrace(); 
    } 
    return obj; 
} 

我怎麼能避免這種情況?兩個類都完全一樣,所以我認爲問題出現在完整的名稱(或ID,或其他)中。

謝謝!

+0

爲什麼你有兩個完全相同的類,但在不同的包中?沒有辦法將一個「轉換」到另一個。您應該重構代碼,以便客戶端和服務器共享一個通用的Packet類。 – wolfcastle

回答

1

爲了擴展djg的答案,問題是你的Packet類不是「完全相同」,因爲它們在不同的包中。

所以解決的辦法是擺脫com.server.serverTracking.Packet並將com.lab.tracking.Packet移動到一個公共庫,android應用程序和服務器端代碼依賴。

這就是說,我會建議不要在Android應用程序和服務器之間使用Java對象序列化。如果您的Packet在新版本中發生任何重大變化(新成員變量等),您可能會破壞以前的所有版本。至少,你應該明確指定一個serialVersionUid。

更好的解決方案是爲數據包字節數組設計一個結構,並使用將字節數組解析爲Java對象的工廠類或構造函數。

0

將數據包實現放在一個核心庫中,android項目和服務器都依賴它。