Maison > Java > javaDidacticiel > le corps du texte

Comment sérialiser des objets polymorphes avec Gson et conserver les membres hérités dans la sortie JSON ?

Linda Hamilton
Libérer: 2024-10-31 21:09:02
original
477 Les gens l'ont consulté

How do you serialize polymorphic objects with Gson and preserve inherited members in the JSON output?

Sérialisation d'objets polymorphes avec Gson

Gson est une bibliothèque Java populaire pour convertir des objets Java vers et depuis JSON. L'un des défis de la sérialisation d'objets avec Gson est la gestion du polymorphisme, dans lequel plusieurs sous-classes héritent d'une superclasse commune.

Problème

Considérez un scénario dans lequel vous avez une hiérarchie de classes avec un classe de base ObixBaseObj et plusieurs classes héritées comme ObixOp. L'objectif est de sérialiser les objets de ces classes en JSON en utilisant Gson tout en préservant les membres hérités (par exemple, in et out pour ObixOp).

Exemple de sérialisation Gson

<code class="java">ObixBaseObj lobbyObj = new ObixBaseObj();
lobbyObj.setIs("obix:Lobby");

ObixOp batchOp = new ObixOp();
batchOp.setName("batch");
batchOp.setIn("obix:BatchIn");
batchOp.setOut("obix:BatchOut");

lobbyObj.addChild(batchOp);

Gson gson = new Gson();
System.out.println(gson.toJson(lobbyObj));</code>
Copier après la connexion

Résultat

<code class="json">{"obix":"obj","is":"obix:Lobby","children":[{"obix":"op","name":"batch"}]}</code>
Copier après la connexion

Remarquez que le JSON sérialisé n'inclut pas les membres hérités d'ObixOp (entrée et sortie).

Solution RuntimeTypeAdapterFactory

Pour gérer le polymorphisme avec élégance, Gson fournit une fonctionnalité puissante appelée RuntimeTypeAdapterFactory. Cette classe enregistre automatiquement les sous-classes dans leur superclasse correspondante pour la sérialisation et la désérialisation.

Implémentation

<code class="java">RuntimeTypeAdapterFactory<ObixBaseObj> adapter = 
                    RuntimeTypeAdapterFactory
                   .of(ObixBaseObj.class)
                   .registerSubtype(ObixBaseObj.class)
                   .registerSubtype(ObixOp.class);


Gson gson2=new GsonBuilder().setPrettyPrinting().registerTypeAdapterFactory(adapter).create();
Gson gson = new Gson();
System.out.println(gson.toJson(lobbyObj));
System.out.println("---------------------");
System.out.println(gson2.toJson(lobbyObj));</code>
Copier après la connexion

Résultat

<code class="json">{"obix":"obj","is":"obix:Lobby","children":[{"obix":"op","name":"batch","children":[]}]}
---------------------
{
  "type": "ObixBaseObj",
  "obix": "obj",
  "is": "obix:Lobby",
  "children": [
    {
      "type": "ObixOp",
      "in": "obix:BatchIn",
      "out": "obix:BatchOut",
      "obix": "op",
      "name": "batch",
      "children": []
    }
  ]
}</code>
Copier après la connexion

Cette solution sérialise correctement tous les membres, y compris ceux hérités des sous-classes.

Gestion de plusieurs sous-classes

Dans les cas où il existe plusieurs sous-classes, RuntimeTypeAdapter de Gson fournit un mécanisme pratique pour les enregistrer.

  1. Créez une classe centralisée pour l'enregistrement des types (par exemple, GsonUtils) :
<code class="java">public class GsonUtils {

    private static final GsonBuilder gsonBuilder = new GsonBuilder()
            .setPrettyPrinting();

    public static void registerType(
            RuntimeTypeAdapterFactory<?> adapter) {
        gsonBuilder.registerTypeAdapterFactory(adapter);
    }

    public static Gson getGson() {
        return gsonBuilder.create();
    }
}</code>
Copier après la connexion
  1. Enregistrez l'adaptateur dans les sous-classes :
<code class="java">public class ObixBaseObj {

    private static final RuntimeTypeAdapterFactory<ObixBaseObj> adapter = 
            RuntimeTypeAdapterFactory.of(ObixBaseObj.class);

    static {
        GsonUtils.registerType(adapter);
    }

    private synchronized void registerClass() {
        if (!registeredClasses.contains(this.getClass())) {
            registeredClasses.add(this.getClass());
            adapter.registerSubtype(this.getClass());
        }
    }

    public ObixBaseObj() {
        registerClass();
        obix = "obj";
    }
}</code>
Copier après la connexion

Cette approche garantit que toutes les sous-classes sont automatiquement enregistrées auprès de GsonBuilder, simplifiant ainsi le processus de sérialisation.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!