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

Format d'échange (XML, JSON...) Java Discussion :

débutant XMLEncoder soucis sérialisation classes


Sujet :

Format d'échange (XML, JSON...) Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Développeur Web
    Inscrit en
    Octobre 2006
    Messages
    66
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Octobre 2006
    Messages : 66
    Par défaut débutant XMLEncoder soucis sérialisation classes
    Bonjour ou bonsoir,
    Je suis nouveau et débutant, et j'ai un projet à faire en java, mais je bloque un peu sur la sérialisation en XML.
    J'aimerais sérialiser en xml de données de classes que j'ai créé, or je n'arrive pas à trouver mon erreur, mon code sérialise les types de donnée simple (Int String, Double) mais dès que je passe à une classe que j'ai créé, j'ai l'exception
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    java.lang.InstantiationException
    mon code :
    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
     
    import java.io.*;
    import java.beans.XMLEncoder;
     
    public class XMLtest{
     
     
    	Obstacle cube=new Obstacle(500,600,400,500);
    	//Double cucu=new Double(20.3);
    	//String cute=new String("okokok");
    	//DInt dd=new DInt(128,64);
     
    	public XMLtest()
    	{
    		try
    		{
    			XMLEncoder e = new XMLEncoder(new BufferedOutputStream(new FileOutputStream("Test.xml")));
    			e.writeObject(cube);
     	     	e.close();
    		}
    		catch(Exception e)
    		{
    			System.out.println(e.getMessage());
    		}
    	}
     
     
    	public class DInt implements Serializable{
    		public int a,b;
    		public DInt(){a=b=0;}
    		public DInt(int x){a=b=x;}
    		public DInt(int x,int y){a=x;b=y;}
    		public DInt(DInt desEntiers){a=desEntiers.a;b=desEntiers.b;}
    	}
     
    	//classe Obstacle
    	public class Obstacle implements Serializable{
    		//x1 : extrémité gauche
    		//x2 : extrémité droite
    		//y1 : extrémité haut
    		//y2 ; extrémité bas
    		public int x1,x2,y1,y2;
     
    		public Obstacle(int x1 , int x2, int y1, int y2)
    		{
    			this.x1=x1;
    			this.x2=x2;
    			this.y1=y1;
    			this.y2=y2;
    		}
     
    		public Obstacle(Obstacle obs2)
    		{
    			x1=obs2.x1;x2=obs2.x2;y1=obs2.y1;y2=obs2.y2;
    		}
    		int getX1(){return x1;}
    		int getX2(){return x2;}
    		int getY1(){return y1;}
    		int getY2(){return y2;}
    		int getX(){return x1;}
    		int getY(){return y1;}
    		int getWidth(){return(x1-x2);}
    		int getHeight(){return(y2-y1);}
    	}//fin définition classe Obstacle
     
     
     
     
    	public static void main(String[] args)
    	{
    		XMLtest test=new XMLtest();
     
    	}
     
    }
    voilà, mon problème est certainement trivial mais je bute dessus.
    La classe Obstacle est une classe que j'ai déjà utilisé pour un autre programme et qui fonctionne.
    Merci d'avance

  2. #2
    Expert confirmé
    Avatar de le y@m's
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2005
    Messages
    2 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2005
    Messages : 2 636
    Par défaut
    Pour pouvoir être sérialisée via un XMLEncoder, une classe doit posséder un constructeur par défaut.
    De plus les champs à sérialiser doivent posséder des accesseurs (get) ET des modifieurs (set).

    Il est toutefois possible de sérialiser une classe ne possédant pas de de constructeur par défaut en utilisant un PersistenceDelegate.
    Tu trouveras plus d'info sur ce points dans le document Using XMLEncoder.

    PS : j'ai récemment commencé à me pencher là dessus en vu d'écrire un tutoriel. Donc, même si je ne connais pas encore très bien tout ces mécanismes, n'hésite pas à poser des questions, ça me permettra de mieux cibler les points et les problèmes à traiter .
    Je ne répondrai à aucune question technique par MP.

    Pensez aux Tutoriels et aux FAQs avant de poster ;) (pour le java il y a aussi JavaSearch), n'oubliez pas non plus la fonction Rechercher.
    Enfin, quand une solution a été trouvée à votre problème
    pensez au tag :resolu:

    Cours Dvp : http://ydisanto.developpez.com
    Blog : http://yann-disanto.blogspot.com/
    Page perso : http://yann-disanto.fr

  3. #3
    Membre confirmé
    Profil pro
    Développeur Web
    Inscrit en
    Octobre 2006
    Messages
    66
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Octobre 2006
    Messages : 66
    Par défaut
    Bon j'ai un peu remanié mon code, je me concentre sur la classe DInt(qui ne contient que deux entiers), j'y ai mis un construteur par défaut (du moins si constructeur par défaut est bien ce que j'appelle constructeur par défaut, à savoir
    j'ai aussi ajouté des accesseurs et des modifieurs, mais idem, toujours la même exception à l'excecution

    mon code :
    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
     
    import java.io.*;
    import java.beans.XMLEncoder;
     
    public class XMLtest{
     
     
    	DInt dd=new DInt(128,64);
     
    	public XMLtest()
    	{
    		try
    		{
    			XMLEncoder e = new XMLEncoder(new BufferedOutputStream(new FileOutputStream("Test.xml")));
    			e.writeObject(dd);
     	     	e.close();
    		}
    		catch(Exception e)
    		{
    			System.out.println(e.getMessage());
    		}
    	}
     
     
    	public class DInt implements Serializable{
    		private int a;
    		private int b;
     
    		public DInt(){a=b=0;}
    		public DInt(int x){a=b=x;}
    		public DInt(int x,int y){a=x;b=y;}
    		public DInt(DInt desEntiers){a=desEntiers.a;b=desEntiers.b;}
     
    		public int geta(){return a;}
    		public int getb(){return b;}
    		public void seta(int a){this.a=a;}
    		public void setb(int b){this.b=b;}
     
    	}
     
     
     
     
     
    	public static void main(String[] args)
    	{
    		XMLtest test=new XMLtest();
     
    	}
     
    }
    PersistenceDelegate, d'après ce que j'ai crû comprendre, c'est une façon de dire au parser comment s'occuper des données de la classe (?).
    Cela dit, apparemment dans la JavaDoc ils disent qu'il vaut mieux utiliser cela de façon ponctuelle et si on a pas d'autre choix. Donc j'aimerais vraiment réussir à faire une classe écrivable en XML sans avoir à bidouiller (histoire de comprendre mon erreur et d'avoir un code à peu près propre ).

    Merci déjà pour les renseignements, ça m'aide à comprendre un peu les mécanisme

  4. #4
    Expert confirmé
    Avatar de le y@m's
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2005
    Messages
    2 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2005
    Messages : 2 636
    Par défaut
    En fait tu ne peux pas sérialiser ta classe DInt car celle ci est une classe interne de la classe XMLtest. Pour pouvoir être sérialisée avec XMLEncoder, une classe ne doit pas être interne et doit être public.

    Une remarque (qui n'a rien à voir avec ton problème), il est préférable de fermer le XMLEncoder dans un bloc finally.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public XMLtest() {
        try {
            XMLEncoder e = new XMLEncoder(new BufferedOutputStream(new FileOutputStream("Test.xml")));
            try {
                e.writeObject(dd);
            } finally {
                e.close();
            }
            catch(Exception e) {
                System.out.println(e.getMessage());
            }
        }
    }
    Il est aussi conseillé, au moins lorsque tu débug, d'afficher la stack trace des exceptions plutôt que simplement le message.
    Je ne répondrai à aucune question technique par MP.

    Pensez aux Tutoriels et aux FAQs avant de poster ;) (pour le java il y a aussi JavaSearch), n'oubliez pas non plus la fonction Rechercher.
    Enfin, quand une solution a été trouvée à votre problème
    pensez au tag :resolu:

    Cours Dvp : http://ydisanto.developpez.com
    Blog : http://yann-disanto.blogspot.com/
    Page perso : http://yann-disanto.fr

  5. #5
    Membre confirmé
    Profil pro
    Développeur Web
    Inscrit en
    Octobre 2006
    Messages
    66
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Octobre 2006
    Messages : 66
    Par défaut
    Comme je l'avais supposé, c'était assez trivial
    Il fallait en fait mettre la classe dans un fichier séparé.

    au final j'ai donc ceci :

    XMLtest.java
    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
     
    //XMLtest.java
     
    import java.io.*;
    import java.beans.XMLEncoder;
     
    public class XMLtest{
     
     
    	DInt dd=new DInt(128,64);
     
    	public XMLtest()
    	{
    		try
    		{
    			XMLEncoder e = new XMLEncoder(new BufferedOutputStream(new FileOutputStream("Test.xml")));
    			e.writeObject(dd);
     	     	e.close();
    		}
    		catch(Exception e)
    		{
    			System.out.println(e.getMessage());
    		}
    	}
     
     
    	public class DInt implements Serializable{
    		private int a;
    		private int b;
     
    		public DInt(){a=b=0;}
    		public DInt(int x){a=b=x;}
    		public DInt(int x,int y){a=x;b=y;}
    		public DInt(DInt desEntiers){a=desEntiers.a;b=desEntiers.b;}
     
    		public int geta(){return a;}
    		public int getb(){return b;}
    		public void seta(int a){this.a=a;}
    		public void setb(int b){this.b=b;}
     
    	}
     
     
     
     
     
    	public static void main(String[] args)
    	{
    		XMLtest test=new XMLtest();
     
    	}
     
    }
    DInt.java
    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
    32
     
    import java.io.*;
    import java.beans.XMLEncoder;
     
    public class XMLtest{
     
     
    	DInt dd=new DInt(128,64);
    	//Obstacle dd=new Obstacle(500,600,400,500);
     
    	public XMLtest()
    	{
    		try
    		{
    			XMLEncoder e = new XMLEncoder(new BufferedOutputStream(new FileOutputStream("Test.xml")));
    			e.writeObject(dd);
     	     	e.close();
    		}
    		catch(Exception e)
    		{
    			System.out.println(e.getMessage());
    		}
    	}
     
     
    	public static void main(String[] args)
    	{
    		XMLtest test=new XMLtest();
     
    	}
     
    }
    Par contre, j'ai essayé avec ma classe Obstacle (4 entiers)
    ça fonctionne, mais mon fichier xml ne comporte pas les info que j'ai sérialisé :/
    Obstacle.java
    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
     
    import java.io.Serializable;
     
    public class Obstacle implements Serializable
    {
    	private int x1;
    	private int x2;
    	private int y1;
    	private int y2;
     
    	public Obstacle(){x1=x2=y1=y2=0;}
    	public Obstacle(int x){x1=x2=y1=y2=x;}
    	public Obstacle(int x1,int x2,int y1,int y2){this.x1=x1;this.x2=x2;this.y1=y1;this.y2=y2;}
    	public Obstacle(Obstacle obs2){x1=obs2.x1;x2=obs2.x2;y1=obs2.y1;y2=obs2.y2;}
     
    	//accesseurs
    	public int getx1(){return x1;}
    	public int getx2(){return x2;}
    	public int gety1(){return y1;}
    	public int gety2(){return y2;}
    	//modificateurs
    	public void setx1(int x1){this.x1=x1;}
    	public void setx2(int x2){this.x2=x2;}
    	public void sety1(int y1){this.y1=y1;}
    	public void sety2(int y2){this.y2=y2;}
     
    }//fin définition classe Obstacle
    test.xml
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    <?xml version="1.0" encoding="UTF-8"?> 
    <java version="1.5.0_07" class="java.beans.XMLDecoder"> 
     <object class="Obstacle"/> 
    </java>

    je conseille par ailleurs cette source trouvée sur Developpez.com

  6. #6
    Expert confirmé
    Avatar de le y@m's
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2005
    Messages
    2 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2005
    Messages : 2 636
    Par défaut
    Je suppose que tu as sérialisé un objet Obstacle instancié avec le constructeur par défaut et que tu ne l'as pas modifié, non ?
    Si oui alors c'est normal car lors de la sérialisation, ton objet est dans son état "initial".
    Le processus de sérialisation XML ne sérialise pas les valeurs par défaut mais uniquement se qui a changé (fait un essai en modifant un attribut, tu veras que celui-ci sera sérialisé mais pas les autres).

    Encore une remarque, l'écriture des accesseurs/modifieurs suit une certaine convention. Ainsi leur nom doit commencer par get/set suivi du nom de l'attribut auquel en met la première lettre en majuscule.
    Dans ta classe Obstacle, cela donne getX1() et pas getx1() (idem pour les attributs de ta classe DInt). Si tu ne suit pas cette convention tu risque d'avoir des problèmes lors de la désérialisation.
    Je ne répondrai à aucune question technique par MP.

    Pensez aux Tutoriels et aux FAQs avant de poster ;) (pour le java il y a aussi JavaSearch), n'oubliez pas non plus la fonction Rechercher.
    Enfin, quand une solution a été trouvée à votre problème
    pensez au tag :resolu:

    Cours Dvp : http://ydisanto.developpez.com
    Blog : http://yann-disanto.blogspot.com/
    Page perso : http://yann-disanto.fr

  7. #7
    Membre confirmé
    Profil pro
    Développeur Web
    Inscrit en
    Octobre 2006
    Messages
    66
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Octobre 2006
    Messages : 66
    Par défaut
    J'ai changé le nom des accesseurs, et ça fonctionne.
    Enfin je trouve ça étrange parce que avec l'autre classe (DInt) les accesseurs n'avaient pas leurs noms à ce format et ça fonctionnait.

    Maintenant, j'ai encore une petite question:
    Si j'ai dans ma classe un tableau ou un Vector, pourra-t-on la sérialiser en xml ?

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

Discussions similaires

  1. [Débutant] Constructeur d'une classe
    Par chennuo dans le forum Langage
    Réponses: 2
    Dernier message: 10/03/2006, 22h17
  2. [Débutant][Appli]Appeller une classe.
    Par Rom780 dans le forum Langage
    Réponses: 10
    Dernier message: 18/02/2006, 11h48
  3. Réponses: 4
    Dernier message: 08/11/2005, 15h10
  4. [Débutant(e)]Instancier une classe connaissant son nom (String)
    Par Invité dans le forum API standards et tierces
    Réponses: 5
    Dernier message: 17/06/2005, 11h05
  5. [Débutant][JNDI] Erreur "bad class file"
    Par giffle dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 05/01/2005, 10h23

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