Ce processus peut également être implémenté via le réseau, qui peut d'abord créer un objet sur la machine Windows, le sérialiser, puis l'envoyer dans une machine Unix sur le réseau, puis le réassembler avec précision. Pourquoi chacun des objets Java RMI, Socket, JMS et EJB passe-t-il?
Le mécanisme de sérialisation des objets Java a généralement deux utilisations:
Java JavaBeans: Les informations sur l'état du bean sont généralement configurées au moment de la conception. .
RMI permet de faire fonctionner des objets sur les machines à distance comme sur les machines natives; ou des programmes qui utilisent des sockets pour transférer des objets sur le réseau, ceux-ci nécessitent la mise en œuvre du mécanisme Serializaiton.
Nous pouvons sérialiser les classes en faisant implémenter l'interface java.io.ierializable. Cette interface est une interface du fabricant. Autrement dit, pour que la classe l'implémente, l'interface n'a besoin d'implémenter aucune méthode. Il est principalement utilisé pour informer les machines virtuelles Java (JVM) qu'un objet doit être sérialisé.
Il y a quelques points que nous devons clarifier pour ceci:
Toutes les classes ne peuvent pas être sérialisées.
Il existe de nombreuses classes de base en Java qui ont implémenté des interfaces sérialisables, telles que la chaîne, le vecteur, etc. Mais par exemple, Hashtable n'implémente pas l'interface sérialisable.
Il existe deux classes principales pour lire ou écrire des objets à Streams: ObjectOutputStream et ObjectInputStream.ObjectOutputStream fournit une méthode WriteObject utilisée pour écrire des objets dans le flux de sortie, et ObjectInputStream fournit une méthode ReadObject pour la lecture d'objets du flux d'entrée. Les objets utilisant ces méthodes doivent avoir été sérialisés. C'est-à-dire que l'interface sérialisable doit avoir été implémentée. Si vous souhaitez écrire un objet de hachage, vous obtiendrez une exception.
Le processus de sérialisation est d'écrire des objets et de lire des objets du flux d'octets. Après avoir converti l'état d'objet en flux d'octets, vous pouvez l'enregistrer en un fichier à l'aide de différentes classes de flux d'octets dans le package java.io, tuyau dans un autre thread ou envoyer des données d'objet à un autre hôte sur une connexion réseau. La fonction de sérialisation des objets est très simple et puissante, et elle est utilisée dans RMI, socket, JMS et EJB. Le problème de sérialisation des objets n'est pas le sujet le plus excitant de la programmation réseau, mais il est assez important et a beaucoup de signification pratique.
La sérialisation des objets peut implémenter des objets distribués. Les principales applications telles que: RMI utilise la sérialisation des objets pour exécuter des services sur des hôtes distants, tout comme lors de l'exécution d'objets sur les machines locales.
La sérialisation de l'objet Java conserve non seulement les données d'un objet, mais enregistre également les données de chaque objet référencées par l'objet. L'ensemble de la hiérarchie d'objets peut être écrit dans un flux d'octets, enregistré dans un fichier ou transmis sur une connexion réseau. La sérialisation de l'objet peut être utilisée pour effectuer une «copie profonde» de l'objet, c'est-à-dire en copie l'objet lui-même et l'objet référencé lui-même. La sérialisation d'un objet peut entraîner la séquence entière d'objets.
La sérialisation Java est relativement simple et ne nécessite généralement pas d'écriture de code personnalisé pour enregistrer et restaurer l'état d'objet. Les objets de classe qui implémentent l'interface java.io.serialisable peuvent être convertis en flux d'octets ou récupérés sans ajouter de code à la classe. Dans de rares cas, le code personnalisé requis pour enregistrer ou restaurer l'état de l'objet. Remarque ici: toutes les classes ne peuvent pas être sérialisées, et certaines classes ne peuvent pas être sérialisées.
Mécanisme de sérialisation:
La sérialisation est divisée en deux parties: la sérialisation et la désérialisation. La sérialisation est la première partie de ce processus, divisant les données en un flux d'octets pour le stockage dans un fichier ou une transmission sur un réseau. La désérialisation consiste à ouvrir le flux d'octets et à reconstruire l'objet. La sérialisation des objets nécessite non seulement la conversion du type de données de base en représentation d'octets, mais parfois aussi la récupération des données. La récupération des données nécessite une instance de l'objet qui restaure les données. Le processus de sérialisation dans ObjectOutputStream est connecté à un flux d'octets, y compris le type d'objet et les informations de version. Pendant la désérialisation, le JVM génère une instance d'objet avec des informations d'en-tête, puis copie les données du flux d'octets d'objet vers les membres de données de l'objet. Expliquons-le en deux parties:
Traitement du flux d'objets: ( processus de sérialisation et processus de désérialisation)
Le package Java.io a deux classes qui sérialisent les objets. ObjectOutputStream est responsable de l'écriture d'objets dans un flux d'octet, et ObjectInputStream reconstruit les objets d'un flux d'octets.
Comprenons d'abord la classe ObjectOutputStream. La classe ObjectOutputStream étend l'interface DataOutput.
La méthode writeObject () est la méthode la plus importante pour la sérialisation des objets. Si l'objet contient des références à d'autres objets, la méthode WriteObject () sérialise récursivement ces objets. Chaque ObjectOutputStream conserve une table de référence d'objet sérialisée pour empêcher l'envoi de plusieurs copies du même objet. (Ceci est important) puisque writeObject () peut sérialiser l'ensemble des objets référencés croisés, la même instance ObjectOutputStream peut accidentellement être invité à sérialiser le même objet. À l'heure actuelle, la sérialisation antireference est réalisée au lieu d'écrire à nouveau dans le flux d'octet d'objet.
Ensuite, comprenons la classe ObjectOutputStream à partir de l'exemple.
La copie de code est la suivante:
// sérialiser la date d'aujourd'hui dans un fichier.
FileoutputStream f = new FileOutputStream ("tmp");
ObjectOutputStream s = new ObjectOutputStream (f);
S.WriteObject ("aujourd'hui");
S.WriteObject (new Date ());
S.Flush ();
Maintenant, comprenons la classe ObjectInputStream. C'est similaire à ObjectOutputStream. Il étend l'interface de datainput. Méthodes dans ObjectInputStream reflète la méthode publique de lecture des types de données Java Basic dans DataRainputStream. La méthode readObject () désérialise un objet d'un flux d'octet. Chaque fois que la méthode readObject () est appelée, l'objet suivant dans le flux est renvoyé. Le flux d'octet d'objet ne transmet pas le bytecode de la classe, mais inclut le nom de classe et sa signature. Lorsque readObject () reçoit l'objet, le JVM charge la classe spécifiée dans l'en-tête. Si cette classe ne peut pas être trouvée, readObject () lance une classe ClassNotFoundException. Le reste des méthodes ObjectInputStream est utilisé pour personnaliser le processus de désérialisation.
Les exemples sont les suivants:
La copie de code est la suivante:
// désérialiser les objets de chaîne et les objets de date du fichier
FileInputStream dans = new FileInputStream ("tmp");
ObjectInputStream s = new ObjectInputStream (in);
String Today = (String) s.ReadObject ();
Date de date = (date) s.readObject ();
Processus de sérialisation personnalisé:
La sérialisation peut généralement être effectuée automatiquement, mais parfois le processus peut être contrôlé. Java peut déclarer les classes comme sérialisables, mais peut toujours contrôler manuellement les membres de données déclarés statiques ou transitoires.
Exemple: une classe de sérialisation très simple.
La copie de code est la suivante:
classe publique SimpleSerializableClass implémente série {
String stoday = "aujourd'hui:";
Date transitoire dttoday = new Date ();
}
Lors du sérialisation, tous les membres de données de la classe doivent être sérialisables, sauf ceux déclarés transitoires ou statiques. Déclarer la variable en tant que transitoire indique au JVM que nous serons responsables de la sérialisation des arguments. Après avoir déclaré un membre de données comme transitoire, le processus de sérialisation ne peut pas l'ajouter au flux d'octets de l'objet et il n'y a pas de données envoyées à partir du membre de données transitoires. Lors de la désérialisation des données par la suite, le membre de données doit être reconstruit (car il fait partie de la définition de la classe), mais ne contient aucune donnée car ce membre de données n'écrit aucune donnée au flux. N'oubliez pas que les flux d'objets ne sérialisent pas statique ou transitoire. Notre classe doit utiliser des méthodes writeObject () et readObject () pour traiter ces membres de données. Lorsque vous utilisez des méthodes writeObject () et readObject (), vous devez également prêter attention à la lecture de ces membres de données dans l'ordre où ils sont écrits.
Certains des codes sur la façon d'utiliser la sérialisation personnalisée sont les suivants
La copie de code est la suivante:
// Réécrivez la méthode writeObject () pour gérer les membres transitoires.
public void writeObject (ObjectOutputStream OutputStream) lève ioException {
outputStream.defaultWriteObject (); // Créez la méthode WriteObject () personnalisée pour
// Utilisez la logique intégrée en sérialisation automatique.
OutputStream.WriteObject (OSOCKET.GetInEtAddress ());
outputStream.WriteInt (osocket.getport ());
}
// Réécrivez la méthode readObject () pour recevoir des membres transitoires.
private void readObject (objectInputStream inputStream) lance ioException,
ClassNotFoundException {
inputStream.defaulTreadObject (); // defaulTreadObject () complète la sérialisation automatique
InetAddress Oaddress = (IneTAddress) inputStream.readObject ();
int iport = inputStream.readInt ();
osocket = new socket (oaddress, iport);
iid = getID ();
dttoday = new Date ();
}
Personnalisez complètement le processus de sérialisation:
Si une classe est complètement responsable de sa propre sérialisation, elle implémente l'interface externalisable au lieu de l'interface sérialisable. La définition de l'interface externalisable comprend deux méthodes writeExternal () et readExternal (). Ces méthodes peuvent être utilisées pour contrôler la façon dont les membres des données d'objet sont écrits dans les flux d'octets. , il n'y a pas du tout de sérialisation automatique. Faites attention ici. La classe de déclaration met en œuvre des interfaces externalisables avec des risques de sécurité importants. Les méthodes WriteExternal () et ReadExternal () sont déclarées publiques et les classes malveillantes peuvent utiliser ces méthodes pour lire et écrire des données d'objets. Si l'objet contient des informations sensibles, soyez très prudent. Cela comprend l'utilisation de sockets sécurisés ou le cryptage de l'ensemble du flux d'octets. À ce stade, nous avons appris la connaissance de base de la sérialisation.