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>
Résultat
<code class="json">{"obix":"obj","is":"obix:Lobby","children":[{"obix":"op","name":"batch"}]}</code>
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>
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>
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.
<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>
<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>
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!