IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Android Discussion :

StreamCorruptedException avec de la désérialisation dans une AsyncTask


Sujet :

Android

  1. #1
    Membre régulier
    Inscrit en
    Novembre 2011
    Messages
    89
    Détails du profil
    Informations forums :
    Inscription : Novembre 2011
    Messages : 89
    Points : 109
    Points
    109
    Par défaut StreamCorruptedException avec de la désérialisation dans une AsyncTask
    Bonjour.
    Je cherche à faire communiquer un serveur tomcat et un appareil android.
    Cependant les roles sont légèrement inversés dans le sens ou c'est l'android qui fait office de "serveur".

    mon objectif est de transmettre un ensemble de données à partir du tomcat et de les transmettre au travers du réseau à l'android en sérialisant mes données.
    Voici la méthode de sérialisation que j'ai coté serveur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public static String serializeObject(Object o) { 
    	ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
     
    	try { 
    		ObjectOutput out = new ObjectOutputStream(bos); 
    		out.writeObject(o); 
    		out.close(); 
    		return bos.toString();
    	} catch(IOException ioe) { 
    	 	return null; 
    	} 
    }
    Je veux envoyer une Map : Map<String, Object> que je remplie avec ma methode export().

    Du coté du serveur tomcat, cela s'envoie ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    try {
    	socket = new Socket(clientPacket.getAddress().getHostAddress(), PORTECOUTE);
    	PrintWriter out = new PrintWriter(new BufferedWriter(
    					new OutputStreamWriter(socket.getOutputStream())),
    					true);
    	Map<String, Object> explist = export();
    	String serialisedobjects = serializeObject(explist); 
    	out.println(serialisedobjects);
     
    	} catch (UnknownHostException e) {
    		e.printStackTrace();
    	} catch (IOException e) {
    		e.printStackTrace();
    	}
    Du coté de l'android :
    j'ai une methode pour déserialiser :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public static Object deserializeObject(String b) { 
    	    try { 
    	      ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(b.getBytes())); 
    	      Object object = in.readObject(); 
    	      in.close(); 
     
    	      return object; 
    	    } catch(ClassNotFoundException cnfe) { 
    	      Log.e("deserializeObject", "class not found error", cnfe); 
     
    	      return null; 
    	    } catch(IOException ioe) { 
    	      Log.e("deserializeObject", "io error", ioe); 
     
    	      return null; 
    	    } 
    	  }
    Enfin, la lecture du coté de l'appareil androidn (dans une AsyncTask appellée LocalServer ):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    	socket = serverSocket.accept();
     
    	BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    	String read = "";
    	Log.d(TAG, "Le serveur ANDROID a recu un message...");
    	while (input.ready()){
    		read = read + ""+ input.readLine();
    	}
     
    	Log.d(TAG, "...de " + read.length() + " caractères.");
    	Map<String, Object> serverdatas = null;
    	serverdatas = (Map<String, Object>) deserializeObject(read);
    	if (serverdatas != null && serverdatas.containsKey("groupes")){
    		Log.d(TAG, "Deserialisation avec succès. ");
    	} else {
    		Log.d(TAG, "Echec de la déserialisation.");
    	}
    	socket.close();
    La déserialisation se passe mal.
    Voici l'erreur qui en est retournée
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    E/deserializeObject(1635): io error
    E/deserializeObject(1635): java.io.StreamCorruptedException
    E/deserializeObject(1635): 	at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:2369)
    E/deserializeObject(1635): 	at java.io.ObjectInputStream.<init>(ObjectInputStream.java:433)
    E/deserializeObject(1635): 	at com.project.network.LocalServer.deserializeObject(LocalServer.java:80)
    E/deserializeObject(1635): 	at com.project.network.LocalServer.doInBackground(LocalServer.java:61)
    E/deserializeObject(1635): 	at com.project.network.LocalServer.doInBackground(LocalServer.java:1)
    E/deserializeObject(1635): 	at android.os.AsyncTask$2.call(AsyncTask.java:185)
    E/deserializeObject(1635): 	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
    E/deserializeObject(1635): 	at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    E/deserializeObject(1635): 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
    E/deserializeObject(1635): 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
    E/deserializeObject(1635): 	at java.lang.Thread.run(Thread.java:1019)
    W/dalvikvm(1635): threadid=11: thread exiting with uncaught exception (group=0x40195560)
    E/AndroidRuntime(1635): FATAL EXCEPTION: AsyncTask #2
    E/AndroidRuntime(1635): java.lang.RuntimeException: An error occured while executing doInBackground()
    E/AndroidRuntime(1635): 	at android.os.AsyncTask$3.done(AsyncTask.java:200)
    E/AndroidRuntime(1635): 	at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
    E/AndroidRuntime(1635): 	at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
    E/AndroidRuntime(1635): 	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
    E/AndroidRuntime(1635): 	at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    E/AndroidRuntime(1635): 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
    E/AndroidRuntime(1635): 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
    E/AndroidRuntime(1635): 	at java.lang.Thread.run(Thread.java:1019)
    E/AndroidRuntime(1635): Caused by: java.lang.NullPointerException
    E/AndroidRuntime(1635): 	at com.project.network.LocalServer.doInBackground(LocalServer.java:62)
    E/AndroidRuntime(1635): 	at com.project.network.LocalServer.doInBackground(LocalServer.java:1)
    E/AndroidRuntime(1635): 	at android.os.AsyncTask$2.call(AsyncTask.java:185)
    E/AndroidRuntime(1635): 	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
    E/AndroidRuntime(1635): 	... 4 more
    En envoyant juste une chaine de caractère sans sérialiser, cela fonctionne.
    Je me pose des questions :
    - si je recupère bien l'ensemble de l'information recue par la socket (que le message n'est pas tronqué)
    - Si je me mélange pas les pinceaux en travaillant avec des objets serialisés en String mais utilisant par moment des Bytes (avec ByteArrayInputStream et son jumeau opposé ^^)

    Merci d'avance pour toute piste qui pourra me faire avancer.

    Edit : Je pense m'etre planté dans la de/serialisation, la transmission d'une simple chaine de caractères sérialisée cette fois-ci reproduit l'erreur.

  2. #2
    Membre régulier
    Inscrit en
    Novembre 2011
    Messages
    89
    Détails du profil
    Informations forums :
    Inscription : Novembre 2011
    Messages : 89
    Points : 109
    Points
    109
    Par défaut
    Personne n'a une idée ?
    le probleme vient tres certainement de la facon dont mes données sont transmises ou déserialisées.

  3. #3
    Membre régulier
    Inscrit en
    Novembre 2011
    Messages
    89
    Détails du profil
    Informations forums :
    Inscription : Novembre 2011
    Messages : 89
    Points : 109
    Points
    109
    Par défaut
    Bonjour,
    il semblerait que ce soit la différence JVM (java 6 d'un coté, Dalvik de l'autre) qui soit a l'origine du probleme.

    Quelqu'un aurait une idée de solution "propre" et simple au possible pour me permettre d'envoyer mes données (une hashmap) entre les deux ?

  4. #4
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 274
    Points : 4 141
    Points
    4 141
    Par défaut
    Ca ne répondra pas directement à ton problème, mais as-tu une bonne raison de procéder de la sorte ?
    La logique voudrait que ce soit au terminal d'aller récupérer auprès du serveur les données sous un format facilement exploitable: xml, json...

    Faire de la sérialisation sur deux plates-formes différentes comme celles-la ne me semble pas etre une bonne idée.

    Au pire si tu veux garder ta méthode avec socket, envoie les données au format texte (xml, json).

  5. #5
    Membre régulier
    Inscrit en
    Novembre 2011
    Messages
    89
    Détails du profil
    Informations forums :
    Inscription : Novembre 2011
    Messages : 89
    Points : 109
    Points
    109
    Par défaut
    Citation Envoyé par fr1man Voir le message
    Ca ne répondra pas directement à ton problème, mais as-tu une bonne raison de procéder de la sorte ?
    La logique voudrait que ce soit au terminal d'aller récupérer auprès du serveur les données sous un format facilement exploitable: xml, json...
    Tout à fait d'accord, hélas, le terminal... ne connait pas l'adresse du serveur.
    Il réalise donc un broadcast en espérant que le serveur réponde. Il répond alors en ouvrant lui même la socket et fournissant la réponse.
    C'est tordu et un brin "ré-invention de la roue" mais bref...

    Pour la sérialisation, cela était en effet une fausse bonne idée... J'avais pas du tout pensé à la différence de JVM.

    Citation Envoyé par fr1man Voir le message
    Au pire si tu veux garder ta méthode avec socket, envoie les données au format texte (xml, json).
    C'est ensuite ce que j'ai fait : j'ai utilisé la librairie Xstream pour encoder ma réponse en XML. De l'autre coté, le client utilise lui aussi Xstream pour passer du XML en Object. Cela fonctionne parfaitement.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème avec des caractères spéciaux dans une chaine
    Par thibaut06 dans le forum Général JavaScript
    Réponses: 11
    Dernier message: 20/11/2006, 16h46
  2. [c#]probleme avec les menu toolStripItem dans une form mdi??
    Par must19 dans le forum Windows Forms
    Réponses: 3
    Dernier message: 05/11/2006, 23h02
  3. [SQL] Problème avec nombre d'enregistrements dans une table
    Par zana74 dans le forum PHP & Base de données
    Réponses: 8
    Dernier message: 14/08/2006, 13h28
  4. Problème avec nombre d'enregistrements dans une table
    Par zana74 dans le forum Langage SQL
    Réponses: 3
    Dernier message: 14/08/2006, 13h21
  5. [VB6] Problème avec la touche 0 dans une MaskEdBox
    Par bb62 dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 02/03/2006, 09h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo