- Open Mind - http://allili.freehostia.com -

La sérialisation binaire en JAVA

Posté par root@khalid le 8 mars 2009 @ 17:18 dans JAVA | 1 commentaire

Entant que développeur, on a recours à enregistrer l’état de nos objets dans la mémoire, fichier … Durant cet article, je vais essayer de présenter le mécanisme de la sérialisation comme solution, et son implémentation sous java.

Définition

La sérialisation est le processus de sauvegarde de l’état d’un objet à destination d’une zone de stockage. La désérialisation est le processus inverse, donc reconstituer l’objet depuis un flux de données.

Sérialisation JAVA

Il existe plusieurs type de sérialisation tels que : La sérialisation binaire, la sérialisation XML…

Sérialisation # Persistance
Il ne faut pas confondre entre la sérialisation et la persistance, la première consiste à une conversion d’un objet en flux de données donc pas de notion de stockage. Quant à  la persistance fait référence au stockage permanant. A vrai dire, la sérialisation peut être utilisé pour assurer la persistance des objets.

Implémentation en JAVA :

La sérialisation a été introduit dans java depuis sa version 1.1. Pour réaliser ce mécanisme sous java, on a besoin de l’interface Serializable, les classes ObjectOutputStream et ObjectInputStream. Une autre interface peut être ajoutée qui est l’interface Externalizable qui nous permet d’implémenter notre propre mécanisme de sérialisation (cet article ne traite pas la sérialisation personnalisée).

L’interface Serializable est interface qui permet d’identifier les classes sérialisables. Donc, pour sérialiser un objet d’une classe donnée, elle doit implémenter l’interface Serializable ou hérite d’une classe elle-même serialisable.
Pour qu’un attribut soit Sérialisé il doit être :

  • De type primitif ou être lui-même serialisable.
  • Pas déclaré en tant que static.
  • Pas déclaré en tant que transient.
  • Ne pas être hérité d’une classe mère non serialisable.

N.B :
Un numéro de version « serialVersionUID » est associé à toute classe serialisable, il permet de tester la correspondance des classes lors de la déserialisation.

Toute classe serialisable doit comporter l’attribut « serialVersionUID » dite le numéro de version. Son rôle est de s’assurer des versions des classes JAVA. Il est de la forme :

private static final long serialVersionUID = 1L;

Afin d’illustrer un exemple pour notre article, on va utiliser la classe suivante :

public class Usere{
private String nom;
private String pass;
public User(String nom, String pass)
{
this.nom=nom;
this.pass=pass;
}
public String get_nom()
{
return nom;
}
public String get_pass()
{
return pass;
}
}

La sérialisation :
La classe ObjectOutputStream représente un flux d’objets, elle implémente l’interface « ObjectOutput » qui nous fournie la possibilité d’écriture des objets. Ainsi, la classe ObjectOutputSteram permet de sérialiser un objet via sa méthode « writeObject() » comme le nous montre la méthode suivant :

public static void serialiser(User user)
{
try {
FileOutputStream fout=new FileOutputStream(”auth.bin”);
ObjectOutputStream oout=new ObjectOutputStream(fout);
oout.writeObject(user);
System.out.println(user.get_nom() + ” a ete serialise”);
oout.close();
fout.close();
} catch(IOException ioe) {
ioe.printStackTrace();
}
}

En gros au modo, cette méthode permet la sérialisation d’un objet User,  mais voyons un peu ce qui existe dans la marmite. Pour sérialiser notre objet on a besoin d’un fichier  (Comme sorte de moyen stockage) pour contenir nos objets, à cette fin on a créé l’objet fout « FileOutputStream » qui as comme paramètre le chemin du fichier « auth.bin » (vous pouvez passer le chemin ou même l’objet FileOutputStream comme paramètre à la méthode).

La création d’un objet ObjectOutputStream qui prend comme paramètre l’instance FileOutputStream va nous permettre de sérialiser l’objet User dans le fichier « auth.bin ».
L’objet oout de la classe ObjectOutputStream prend comme paramètre l’objet fout va nous permettre de sérialiser notre objet user de la classe User grâce à sa méthode writeObject(). La clôture des objets oout et fout ainsi que le traitement des exceptions est primordiale.

La déserialisation :
La classe ObjectInputStream implémente l’interface « ObjectInput » qui nous fournie la possibilité de lire carrément un objet à partir d’un flux de données tels que les fichiers. Donc la déserialisation est déployée grâce aux objets de la classe ObjectInputStream via la méthode « readObject() » qui retourne à un objet de la classe Object, comme nous le montre cette exemple :

public static User deserialiser()
{
User user=null;
try {
FileInputStream fin=new FileInputStream(”auth.bin”);
ObjectInputStream oin=new ObjectInputStream(fin);
user=(User)oin.readObject();
System.out.println(user.get_nom() + ” a ete deserialise”);
oin.close();
fin.close();
}catch(ClassNotFoundException nfe) {
nfe.printStackTrace();
} catch(IOException ioe) {
ioe.printStackTrace();
}
return user;
}

Cette méthode permet de désérialiser un objet User, il s’agit d’une lecture de l’objet à partir du fichier « auth.bin ». En effet, pour la lecture des objets nous avons besoin de l’objet fin de la classe FileInputStream qui prend comme paramètre le chemin du fichier « auth.bin » (vous pouvez passer le chemin ou même l’objet FileInputStream comme paramètre à la méthode).

L’objet oin de la classe ObjectInputStream qui prend comme paramètre l’objet fin permet de lire un objet depuis le fichier « auth.bin » via l’appel de la méthode readObject(), donc il va falloir faire un cast pour retourner un objet User. Idem à la sérialisation, la clôture des fin et oin ainsi que le traitement des exceptions est primordiale.
La classe User :

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class User implements Serializable{/**
*
*/private static final long serialVersionUID = 1L;
private String nom;
private String pass;
public User(String nom, String pass)
{
this.nom=nom;
this.pass=pass;
}
public String get_nom()
{
return nom;
}
public String get_pass()
{
return pass;
}
public static void serialiser(User user)
{
try {
FileOutputStream fout=new FileOutputStream(”auth.bin”);
ObjectOutputStream oout=new ObjectOutputStream(fout);
oout.writeObject(user);
//oout.flush();
System.out.println(user.get_nom() + ” a ete serialise”);
oout.close();
fout.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
public static User deserialiser()
{
User user=null;
try {
FileInputStream fin=new FileInputStream(”auth.bin”);
ObjectInputStream oin=new ObjectInputStream(fin);
user=(User)oin.readObject();
System.out.println(user.get_nom() + ” a ete deserialise”);
oin.close();
fin.close();
}catch(ClassNotFoundException nfe) {
nfe.printStackTrace();
} catch(IOException ioe) {
ioe.printStackTrace();
}
return user;
}
}

La sérialisation partielle :
Jusqu’à maintenant, on a vu la sérialisation et la déserialisation mais il semble que ces mécanises prend en charge tout les attributs de la classes!!! Pas du tout, pour une raison ou une autre on ne veut sérialiser qu’une partie des attributs et cela est réalisé grâce au mot clé transient. Comme exemple pour la classe User, pour des raisons de sécurité,  on ne va pas sérialiser le mot de passe et donc la classe devienne comme suit :

public class User implements Serializable{
private static final long serialVersionUID = 1L;
private String nom;
transient private String pass;

}

Code Source :
Le code source de l’exemple est disponible ici.


Article provenant de Open Mind: http://allili.freehostia.com

URL de l'article: http://allili.freehostia.com/java/la-serialisation-binaire-en-java

Copyright © Khalid ALLILI. Cet article est sous licence Creative Commons Attribution-Noncommercial 3.0 License.