Artikelformat

Gson – google json library (Teil 2)

Im ersten Teil zum Thema Gson gab es ja bereits einen kurzen Überblick, wie man Gson grundsätzlich nutzt. Im heutigen zwiten Teil gehen wir einen Schritt weiter und schauen uns die Deserializer genauer an. Diese sind vor allem dann sehr interessant, wenn man eine Fremd-Rest-API nutzen möchte. Die Json Struktur und die daraus direkt resultierenden Java-Objekte können nämlich nicht der Vorstellung entsprechen, die man von einer schönen API hat.

Normalerweise wandelt Gson ein Json in die Objekte um, die ausgehend von der Eingangsklasse definiert sind. Dort findet man üblicherweise Objekte wie String, Integer, Boolean etc und natürlich auch weitere Java Klassen. Möchte man beispielsweise statt eines String ein Enumerator erhalten, so muss man Gson etwas unterstützen. Angenommen wir haben folgenden Enumerator:

public enum SocialMediaNetwork {
    
    TWITTER("tw", "twitter"), 
    GOOGLE_PLUS("gp","googleplus"),
    UNKNOWN("","");
    
    // network short name
    private final String shortName;
    
    // network long name
    private final String longName;

    private SocialMediaNetwork(String shortName, String longName) {
        this.shortName = shortName;
        this.longName = longName;
    }

    public String getShortName() {
        return shortName;
    }

   public String getLongName() {
        return longName;
    }
    
    public static SocialMediaNetwork getEnumFromShortName(String shortName) {
        for(SocialMediaNetwork network: SocialMediaNetwork.values()) {
            if (network.getShortName().equals(shortName)) {
                return network;
            }
        }
        
        return UNKNOWN;
    }
}

Der Enumerator stellt fasst verschiedene SocialMedia-Netzwerke zusammen und stellt Strings bereit, die im weiteren Code benutzt werden. Hat man nun einen shortName kann man auch das passende Enum erzeugen.

Nehmen wir nun an, dass wir folgendes Json-Fragment haben:

{
    "id": "26565946",
    "network": "tw"
}

Dieses Objekt hat eine id, die wir durch einen String repräsentieren können und ein network, dass normalerweise ebenfalls ein String ist. Wir wandeln aber das network-Attribut in ein SocialMediaNetwork Enum um. Zuerst werfen wir noch einen kurzen Blick auf das Java-Objekt:

public class Identifier {
   private String id;
   private SocialMediaNetwork network;

   public String getId() {
      return this.id;
   }

   public SocialMediaNetwork getNetwork() {
      return this.network;
   }
}

Nach dieser Vorarbeit kommen wir zum eigentlichen Deserializer. Dieser wandelt den network-String in unser Enum um. In weiser Voraussicht gibt es im Enum eine statische Methode, die man im Deserializer gleich nutzen kann und somit sieht der Code folgendermaßen aus:

class SocialMediaNetworkDeserializer implements JsonDeserializer<SocialMediaNetwork>{

    public SocialMediaNetwork deserialize(JsonElement json, Type type, JsonDeserializationContext jdc) throws JsonParseException {
        return SocialMediaNetwork.getEnumFromShortName(json.getAsString());
    }
    
}

Der Deserializer implementiert immer den JsonDeserializer. Dieser bekommt als Generic noch den Typ des Objekts mitgegeben, in welchen das vorliegende Json deserialisiert werden soll. Das entspricht dann eben dem Rückgabewert der deserialize-Methode. In dieser Methode müssen wir die Logik implementieren, die dazu notwendig ist das Json-Artefakt in ein Java-Objekt zu deserialisieren. Wir nehmen dazu das JsonElement und stecken dieses als String in die statische Methode des Enums. Und erhalten schon unser Enum, oder wenn etwas schief geht den Fallback-Wert UNKNOWN.

Schreibe einen Kommentar

Pflichtfelder sind mit * markiert.