2009-03-24 6 views
5

Je suis en train de sérialisation et la désérialisation une liste de tableau avec un objet à l'intérieur:Impossible de sérialiser/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(); 
} 

L'objet HairList est également un objet sérialisable.

Cette exécution de code retourne l'erreur suivante:

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

en ligne paramDecoded = (ArrayList<HairBirt>) obj_in.readObject();

Je ne sais pas ce que je fais mal. Pouvez-vous donner un pourboire?

Mise à jour:

Résolue: juste utilisé un tableau natif de HairBirt au lieu d'un ArrayList et il fonctionne:

HairBirt[] list = new HairBirt[x]; 

au lieu de

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

Merci à tous pour ton aide.

Répondre

9

N'utilisez pas ByteArrayOutputStream.toString() - utilisez à la place toByteArray() et codez en base64 les données binaires pour les convertir en chaîne sans perdre d'informations.

Je soupçonne fortement que c'est le problème principal - que vous perdiez les données après la sérialisation. Vous devriez probablement également fermer ou au moins vider le ObjectOutputStream. Je ne sais pas si cela fait vraiment quoi que ce soit dans ce cas, mais cela semble être une bonne idée.

Je ne crois pas qu'il existe un support base64 directement dans Java (dans une classe publique, de toute façon), mais il existe différentes bibliothèques tierces que vous pouvez utiliser, telles que the one in the Apache Commons Codec library.

+0

Yup, c'est le problème, mais j'ai vraiment besoin d'utiliser String sur ce mouvement ... Ce n'est pas le vrai problème, c'est une simplification. – sakana

+0

Que voulez-vous dire par «sur ce mouvement»? Vous devrez * convertir * le BAOS en chaîne sans perte si vous voulez pouvoir le désérialiser. Que ce soit avec base64 ou non est une question différente, mais je pense que c'est une bonne façon de le faire. –

+0

@sakana: base64 est un format de chaîne avec un jeu de caractères limité. – Powerlord

0

Avez-vous essayé de surcharger ce comportement en déclarant votre propre serialVersionUID dans votre classe personnalisée?

Avez-vous une raison spécifique de faire l'étape supplémentaire de sérialisation à travers une chaîne? Normalement, vous désérialisez simplement via un ObjectOutputStream.

+0

Déclarer un serialVersionUID ne aide pas ici. –