2009-03-24 32 views
5

Tôi đang cố gắng để serialize và deserialize array list với một đối tượng bên trong:không thể serialize/Deserialize ArrayList

HairBirt param = new HairBirt(); 
param.setName("name"); 
param.setValue(2.3f); 

HairBirt param2 = new HairBirt(); 
param2.setName("name2"); 
param2.setValue(2.4f); 

ArrayList<HairBirt> list = new ArrayList<HairBirt>(); 

list.add(param); 

list.add(param2); 

ByteArrayOutputStream bos = null; 
try { 
    bos = new ByteArrayOutputStream(); 
    ObjectOutputStream obj_out = new ObjectOutputStream(bos); 
    obj_out.writeObject(list); 
} catch (IOException e) { 
    e.printStackTrace(); 
} 

String encoded = bos.toString(); 
try { 
    encoded = URLEncoder.encode(encoded, "UTF-8"); 
} catch (UnsupportedEncodingException e1) { 
    e1.printStackTrace(); 
} 
System.out.print("The serialized output is: " + encoded); 

//DECODE 

ArrayList<HairBirt> paramDecoded; 

String myParam = null; 
try { 
    myParam = URLDecoder.decode(encoded, "UTF-8"); 
} catch (UnsupportedEncodingException e1) { 
    e1.printStackTrace(); 
} 
System.out.println("Got parameters"); 
ByteArrayInputStream bis = new ByteArrayInputStream(myParam.getBytes()); 

try { 
    ObjectInputStream obj_in = new ObjectInputStream(bis); 

    paramDecoded = (ArrayList<HairBirt>) obj_in.readObject(); 
} catch (IOException e) { 
    e.printStackTrace(); 
} catch (ClassNotFoundException e) { 
    e.printStackTrace(); 
} 

đối tượng Các HairList cũng là một đối tượng serializable.

Mã này thực hiện đang trở lại các lỗi sau:

java.io.InvalidClassException: java.util.ArrayList; local class incompatible: stream classdesc serialVersionUID = 8664875232659988799, local class serialVersionUID = 8683452581122892189

phù paramDecoded = (ArrayList<HairBirt>) obj_in.readObject();

Tôi không biết những gì tôi đang làm sai. Bạn có thể đưa ra một mẹo không?

Cập nhật:

giải quyết: Chỉ cần sử dụng một mảng mẹ đẻ của HairBirt thay vì một ArrayList và nó hoạt động:

HairBirt[] list = new HairBirt[x]; 

thay vì

ArrayList<HairBirt> list = new ArrayList<HairBirt>(); 

Cảm ơn Quý doanh nghiệp đã sự giúp đỡ của bạn.

Trả lời

9

Không sử dụng ByteArrayOutputStream.toString() - thay vào đó, hãy sử dụng toByteArray() và mã hóa base64 để dữ liệu nhị phân chuyển đổi thành chuỗi mà không làm mất thông tin.

Tôi thật sự nghi ngờ đó là vấn đề chính - bạn đã mất dữ liệu sau khi đăng chuỗi. Bạn có lẽ cũng nên đóng hoặc ít nhất là tuôn ra các ObjectOutputStream. Tôi không biết liệu điều đó có thực sự xảy ra trong trường hợp này hay không, nhưng nó có vẻ là một ý hay.

Tôi không tin rằng có bất kỳ hỗ trợ base64 trực tiếp nào trong Java (trong lớp công khai), nhưng có nhiều thư viện bên thứ ba khác nhau mà bạn có thể sử dụng, chẳng hạn như the one in the Apache Commons Codec library.

+0

Yup, đó là vấn đề, nhưng tôi thực sự cần phải sử dụng chuỗi trên di chuyển đó ... Đây không phải là vấn đề thực sự, đó là một sự đơn giản hóa của nó. – sakana

+0

Ý bạn là gì khi 'di chuyển'? Bạn sẽ * có * để chuyển đổi BAOS thành một chuỗi theo cách mất mát nếu bạn muốn có khả năng deserialize nó. Cho dù đó là với base64 hay không là một vấn đề khác nhau, nhưng tôi nghĩ rằng đó là một cách tốt để làm điều đó. –

+0

@sakana: base64 là định dạng chuỗi có bộ ký tự giới hạn. – Powerlord

0

Bạn đã cố gắng ghi đè hành vi này bằng cách khai báo serialVersionUID của riêng bạn trong lớp tùy chỉnh của bạn chưa?

Bạn có lý do cụ thể để thực hiện thêm bước tuần tự hóa thông qua chuỗi không? Thông thường bạn sẽ chỉ deserialize thông qua một ObjectOutputStream.

+0

Khai báo một serialVersionUID không giúp ích gì ở đây. –