![]() |
Mon site perso a changé d'adresse. Si rien ne se passe cliquez sur le lien ci-dessus. |
|
|
|
|
|
|
Développons en Java v 0.85 béta | |
| Copyright (C) 1999-2005 Jean-Michel DOUDOUX |
![]() |
![]() |
![]() |
La sérialisation est un procédé introduit dans le JDK version 1.1 qui permet de rendre un objet persistant. Cet objet est mis sous une forme sous laquelle il pourra être reconstitué à l'identique. Ainsi il pourra être stocké sur un disque dur ou transmis au travers d'un réseau pour le créer dans une autre JVM. C'est le procédé qui est utilisé par RMI. La sérialisation est aussi utilisée par les beans pour sauvegarder leurs états.
Au travers de ce mécanisme, Java fourni une façon facile, transparente et standard de réaliser cette opération : ceci permet de facilement mettre en place un mécanisme de persistance. Il est de ce fait inutile de créer un format particulier pour sauvegarder et relire un objet. Le format utilisé est indépendant du système d'exploitation. Ainsi, un objet sérialisé sur un système peut être réutilisé par un autre système pour récréer l'objet.
L'ajout d'un attribut à l'objet est automatiquement pris en compte lors de la sérialisation. Attention toutefois, la déserialisation de l'objet doit se faire avec la classe qui a été utilisée pour la sérialisation.
La sérialisation peut s'appliquer facilement à tous les objets.
Ce chapitre contient plusieurs sections :
La sérialisation utilise l'interface Serializable et les classes ObjectOutputStream et ObjectInputStream
Cette interface ne définit aucune méthode mais permet simplement de marquer une classe comme pouvant être sérialisée.
Tout objet qui doit être sérialisé doit implémenter cette interface ou une de ses classes mères doit l'implémenter.
Si l'on tente de sérialiser un objet qui n'implémente pas l'interface Serializable, une exception NotSerializableException est levée.
| Exemple ( code Java 1.1 ) : une classe serializable possédant trois attributs |
|
Cette classe permet de sérialiser un objet.
| Exemple ( code Java 1.1 ) : sérialisation d'un objet et enregistrement sur le disque dur |
|
On définit un fichier avec la classe FileOutputStream. On instancie un objet de classe ObjectOutputStream en lui fournissant en paramètre le fichier : ainsi, le résultat de la sérialisation sera envoyé dans le fichier.
On appelle la méthode writeObject en lui passant en paramètre l'objet à sérialiser. On appelle la méthode flush() pour vider le tampon dans le fichier et la méthode close() pour terminer l'opération.
Lors de ces opérations une exception de type IOException peut être levée si un problème intervient avec le fichier.
Après l'exécution de cet exemple, un fichier nommé « personne.ser » est créé. On peut visualiser son contenu mais surtout pas le modifier car sinon il serait corrompu. En effet, les données contenues dans ce fichier ne sont pas toutes au format caractères.
La classe ObjectOutputStream contient aussi plusieurs méthodes qui permettent de sérialiser des types élémentaires et non des objets : writeInt, writeDouble, writeFloat ...
Il est possible dans un même flux d'écrire plusieurs objets les uns à la suite des autres. Ainsi plusieurs objets peuvent être sauvegardés. Dans ce cas, il faut faire attention de relire les objets dans leur ordre d'écriture.
Cette classe permet de déssérialiser un objet.
| Exemple ( code Java 1.1 ) : |
|
| Résultat : |
|
On créer un objet de la classe FileInputStream qui représente le fichier contenant l'objet sérialisé. On créer un objet de type ObjectInputStream en lui passant le fichier en paramètre. Un appel à la méthode readObject() retourne l'objet avec un type Object. Un cast est nécessaire pour obtenir le type de l'objet. La méthode close() permet de terminer l'opération.
Si la classe a changée entre le moment ou elle a été sérialisée et le moment ou elle est déserialisée, une exception est levée :
| Exemple : la classe Personne est modifiée et recompilée |
|
Une exception de type StreamCorruptedException peut être levée si le fichier a été corrompu par exemple en le modifiant avec un éditeur.
| Exemple : les 2 premiers octets du fichier personne.ser ont été modifiés avec un éditeur hexa |
|
Une exception de type ClassNotFoundException peut être levée si l'objet est transtypé vers une classe qui n'existe plus ou pas au moment de l'exécution.
| Exemple ( code Java 1.1 ) : |
|
La classe ObjectInputStream possède de la même façon que la classe ObjectOutputStream des méthodes pour lire des données de type primitives : readInt(), readDouble(), readFloat ...
Lors de la deserialisation, le constructeur de l'objet n'est jamais utilisé.
Le contenu des attributs est visible dans le flux dans lequel est sérialisé l'objet. Il est ainsi possible pour toute personne ayant accès au flux de voir le contenu de chaque attribut même si ceux si sont private. Ceci peut poser des problèmes de sécurité surtout si les données sont sensibles.
Java introduit le mot clé transient qui précise que l'attribut qu'il qualifie ne doit pas être inclus dans un processus de serailisation et donc de deserialisation.
| Exemple ( code Java 1.1 ) : |
|
Lors de la deserialisation, les champs transient sont initialisés avec la valeur null. Ceci peut poser des problèmes à l'objet qui doit gérer cette état pour éviter d'avoir des exceptions de type NullPointerException.
Il est possible de personnaliser la serialisation d'un objet. Dans ce cas, la classe doit implémenter l'interface Externalizable qui hérite de l'interface Serializable.
Cette interface définit deux méthode : readExternal() et writeExternal().
Par défaut, la serialisation d'un objet qui implémente cette interface ne prend en compte aucun attribut de l'objet.
Remarque : le mot clé transient est donc inutile avec un classe qui implémente l'interface Externalisable
![]() |
|
La suite de cette section sera développée dans une version future de ce document
|
|
|
|
|
|
|
Développons en Java v 0.85 béta | ||
| Copyright (C) 1999-2005 Jean-Michel DOUDOUX |