Sérialisation XML en Java? [fermé]

104

Quel est l'analogue Java de la sérialisation XML de .NET?

Dmitry Shechtman
la source
6
Ah, les temps anciens glorieux où les questions à une seule ligne comme celle-ci étaient les bienvenues sur SO. Tellement utile. Sans tout cela "Qu'avez-vous essayé?" / "Fournissez des détails" que les gens aiment lire aujourd'hui.
GOTO 0

Réponses:

81

2008 Answer L'API Java "officielle" pour cela est maintenant JAXB - API Java pour la liaison XML. Voir le didacticiel d'Oracle . L'implémentation de référence se trouve sur http://jaxb.java.net/

Mise à jour 2018 Notez que les modules Java EE et CORBA sont obsolètes dans SE dans JDK9 et doivent être supprimés de SE dans JDK11 . Par conséquent, pour utiliser JAXB, il devra soit être dans votre environnement de classe entreprise existant fourni par votre serveur d'application, par exemple, soit vous devrez l'introduire manuellement.

Cheekysoft
la source
2
C'est vrai, JAXB est certainement la meilleure option!
ivan_ivanovich_ivanoff
1
JAXB a été supprimé des distributions Java standard à partir de Java 10, ce qui en fait désormais une bibliothèque que vous devez regrouper avec votre application si vous le souhaitez, sauf si vous opérez dans un contexte qui le regroupe déjà pour vous.
Theodore Murdock
69

XStream est assez bon pour sérialiser des objets en XML sans trop de configuration et d'argent! (c'est sous licence BSD).

Nous l'avons utilisé dans l'un de nos projets pour remplacer l'ancienne sérialisation java et cela a fonctionné presque immédiatement.

Barak Schiller
la source
3
Très utile, il peut cependant avoir des problèmes sur les structures arborescentes compliquées telles que JGraph avec des objets de nœud sans chaîne.
mikek3332002
Plus simple et mieux que d'autres solutions
daitangio
J'aime XStream. La seule chose est que je ne comprends pas pourquoi un caractère est ajouté avant le XML réel.
James P.
17

Projet "Sérialisation XML simple"

Vous voudrez peut-être examiner le projet de sérialisation XML simple . C'est la chose la plus proche que j'ai trouvée de la System.Xml.Serialization dans .Net.

ARKBAN
la source
Il nécessite cependant des annotations de mappage pour chaque champ.
mP.
1
Pas vrai, je n'en ai pas besoin. Vous pouvez modifier le comportement par défaut et il utilisera uniquement les champs présents.
damluar
1
J'approuve aussi chaleureusement "Simple" . Je l'ai utilisé sur quelques projets avec beaucoup de succès. "Simple" est en effet beaucoup plus simple que JAXB. Le plus approprié lorsque vous avez des besoins relativement simples: Objets obtenus qui doivent être écrits dans le stockage pour être réhydratés ultérieurement en tant qu'objets. JAXB a beaucoup plus de fonctionnalités et de flexibilité, mais c'est une sorte de "80/20", la plupart du temps dans la plupart des projets, vous n'aurez besoin que d'un simple sous-ensemble de fonctionnalités.
Basil Bourque
Fonctionne bien si vous voulez juste un mappage 1: 1. Si vos classes évoluent et que vous avez encore besoin de désérialiser l'ancien XML, vous rencontrez des problèmes car la documentation et les messages d'erreur sont quelque peu vagues. Diagnostiquer le problème est généralement faisable, mais trouver comment le résoudre peut prendre plusieurs jours.
toolforger
13

JAXB fait partie de l'édition standard de JDK version 1.6+. Il en est ainsi FREEet aucune bibliothèque supplémentaire à télécharger et à gérer. Un exemple simple peut être trouvé ici

XStream semble être mort. La dernière mise à jour date du 6 décembre 2008. Simplesemble aussi simple et simple que JAXB mais je n'ai trouvé aucune information de licence pour l'évaluer pour une utilisation en entreprise.

so_mv
la source
4
XStream n'est pas mort, il est juste mature et stable - ce qui signifie qu'il n'y a pas grand chose à ajouter aux fonctionnalités de base. Il en va de même pour l'implémentation de référence JAXB, peu d'activité au cours des dernières années.
StaxMan
9

Il convient de mentionner que depuis la version 1.4, Java avait les classes java.beans.XMLEncoder et java.beans.XMLDecoder. Ces classes effectuent un codage XML qui est au moins très comparable à la sérialisation XML et, dans certaines circonstances, peuvent faire l'affaire pour vous.

Si votre classe s'en tient à la spécification JavaBeans pour ses getters et setters, cette méthode est simple à utiliser et vous n'avez pas besoin d'un schéma. Avec les mises en garde suivantes:

  • Comme avec la sérialisation Java normale
    • codage et décodage exécutés sur un InputStream et OutputStream
    • le processus utilise les méthodes familières writeObject et readObject
  • Contrairement à la sérialisation Java normale
    • l'encodage mais aussi le décodage provoquent l'appel des constructeurs et des initialiseurs
    • l'encodage et le décodage fonctionnent que votre classe implémente ou non Serializable
    • les modificateurs transitoires ne sont pas pris en compte
    • fonctionne uniquement pour les classes publiques, qui ont des constructeurs publics

Par exemple, prenez la déclaration suivante:

public class NPair {
  public NPair() { }
  int number1 = 0;
  int number2 = 0;
  public void setNumber1(int value) { number1 = value;}
  public int getNumber1() { return number1; }
  public void setNumber2(int value) { number2 = value; }
  public int getNumber2() {return number2;}
}

Exécution de ce code:

NPair fe = new NPair();
fe.setNumber1(12);
fe.setNumber2(13);
FileOutputStream fos1 = new FileOutputStream("d:\\ser.xml");
java.beans.XMLEncoder xe1 = new java.beans.XMLEncoder(fos1);
xe1.writeObject(fe);
xe1.close();

Se traduirait par le fichier suivant:

<?xml version="1.0" encoding="UTF-8"?>
<java version="1.7.0_02" class="java.beans.XMLDecoder">
 <object class="NPair">
  <void property="number1">
   <int>12</int>
  </void>
  <void property="number2">
   <int>13</int>
  </void>
 </object>
</java>
Mishax
la source
Sachez que l'utilisation java.beans.XMLDecoderavec les données fournies par l'utilisateur peut introduire des vulnérabilités d'exécution de code arbitraire dans votre code.
aventurin
2

XMLBeans fonctionne très bien si vous avez un schéma pour votre XML. Il crée des objets Java pour le schéma et crée des méthodes d'analyse faciles à utiliser.

John Meagher
la source
0

Si vous parlez de la sérialisation XML automatique des objets, consultez Castor :

Castor est un framework de liaison de données Open Source pour Java [tm]. C'est le chemin le plus court entre les objets Java, les documents XML et les tables relationnelles. Castor fournit la liaison Java vers XML, la persistance Java vers SQL, etc.

Théo
la source
0

Habituellement, j'utilise jaxb ou XMLBeans si j'ai besoin de créer des objets sérialisables en XML. Maintenant, je peux voir que XStream pourrait être très utile car il n'est pas intrusif et possède une API vraiment simple. Je vais bientôt jouer avec et l'utiliser probablement. Le seul inconvénient que j'ai remarqué est que je ne peux pas créer mon propre identifiant d'objet pour les références croisées.

@Barak Schiller
Merci d'avoir publié le lien vers XStream!

Bartosz Bierkowski
la source
Le problème est jaxb et xmlbeans nécessitent un schéma de mappage et ne sont pas auto ...
mP.
0

si vous voulez une solution structurée (comme ORM) alors JAXB2 est une bonne solution.

Si vous voulez une sérialisation comme DOT NET, vous pouvez utiliser la persistance à long terme des composants JavaBeans

Le choix dépend de l'utilisation de la sérialisation.

m.genova
la source
-1
public static String genXmlTag(String tagName, String innerXml, String properties )
{
    return String.format("<%s %s>%s</%s>", tagName, properties, innerXml, tagName);
}

public static String genXmlTag(String tagName, String innerXml )
{
    return genXmlTag(tagName, innerXml, "");
}

public static <T> String serializeXML(List<T> list)
{
    String result = "";
    if (list.size() > 0)
    {
        T tmp = list.get(0);
        String clsName = tmp.getClass().getName();
        String[] splitCls = clsName.split("\\.");
        clsName = splitCls[splitCls.length - 1];
        Field[] fields = tmp.getClass().getFields();

        for (T t : list)
        {
            String row = "";
            try {
                for (Field f : fields)
                {
                    Object value = f.get(t);
                    row += genXmlTag(f.getName(), value == null ? "" : value.toString());
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            row = genXmlTag(clsName, row);

            result += row;
        }
    }

    result = genXmlTag("root", result);
    return result;
}
user4067649
la source
Beaucoup de problèmes: Réinvention de la classe # getSimpleName *** Réinvention de PropertyDescriptor *** Suppose que toutes les propriétés sont des champs accessibles *** Ne cache pas les résultats de réflexion (lent) *** Aucun moyen de personnaliser quoi que ce soit (par exemple, je devrais remplacer noms de classe et de fichier) *** Pas de désérialisation
toolforger