Kartenserialisierung und Deserialisierung mit Jackson

1. Übersicht

In diesem Artikel befassen wir uns mit der Serialisierung und Deserialisierung von Java-Karten mit Jackson .

Wir werden veranschaulichen, wie Map , Map und Map zu und von JSON-formatierten Strings serialisiert und deserialisiert werden .

2. Maven-Konfiguration

 com.fasterxml.jackson.core jackson-databind 2.11.1 

Die neueste Version von Jackson erhalten Sie hier.

3. Serialisierung

Durch die Serialisierung wird ein Java-Objekt in einen Bytestrom konvertiert, der nach Bedarf beibehalten oder gemeinsam genutzt werden kann. Java Karten sind Sammlungen , die eine Schlüssel Karte Objekt auf einen Wert Objekt und sind oft die am wenigsten intuitive Objekte serialisiert werden .

3.1. Karte Serialisierung

Für den einfachen Fall erstellen wir eine Map und serialisieren sie in JSON:

Map map = new HashMap(); map.put("key", "value"); ObjectMapper mapper = new ObjectMapper(); String jsonResult = mapper.writerWithDefaultPrettyPrinter() .writeValueAsString(map);

ObjectMapper ist Jacksons Serialisierungs-Mapper, mit dem wir unsere Map mithilfe der toString () -Methode in String serialisieren und als hübsch gedruckten JSON- String ausschreiben können :

{ "key" : "value" }

3.2. Karte Serialisierung

Mit ein paar zusätzlichen Schritten können Sie eine Karte mit einer benutzerdefinierten Java-Klasse serialisieren. Erstellen wir eine MyPair- Klasse, um ein Paar verwandter String- Objekte darzustellen .

Hinweis: Die Getter / Setter sollten öffentlich sein, und wir kommentieren toString () mit @JsonValue , um sicherzustellen , dass Jackson diesen benutzerdefinierten toString () bei der Serialisierung verwendet:

public class MyPair { private String first; private String second; @Override @JsonValue public String toString() { return first + " and " + second; } // standard getter, setters, equals, hashCode, constructors }

Lassen Sie uns nun Jackson sagen, wie er MyPair serialisiert, indem er Jacksons JsonSerializer erweitert :

public class MyPairSerializer extends JsonSerializer { private ObjectMapper mapper = new ObjectMapper(); @Override public void serialize(MyPair value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException { StringWriter writer = new StringWriter(); mapper.writeValue(writer, value); gen.writeFieldName(writer.toString()); } }

JsonSerializer , wie der Name schon sagt, serialisiert MyPair zu JSON Verwendung MyPair ‚s toString () Methode. Jackson bietet viele Serializer-Klassen an, die Ihren Serialisierungsanforderungen entsprechen.

Wir wenden MyPairSerializer auf unsere Karte mit der @JsonSerialize Anmerkung. Beachten Sie, dass wir Jackson nur erklärt haben, wie MyPair serialisiert wird, da er bereits weiß, wie er String serialisiert :

@JsonSerialize(keyUsing = MyPairSerializer.class) Map map;

Testen wir unsere Kartenserialisierung:

map = new HashMap(); MyPair key = new MyPair("Abbott", "Costello"); map.put(key, "Comedy"); String jsonResult = mapper.writerWithDefaultPrettyPrinter() .writeValueAsString(map);

Die serialisierte JSON-Ausgabe lautet:

{ "Abbott and Costello" : "Comedy" }

3.3. Karte Serialisierung

Der komplexeste Fall ist das Serialisieren einer Karte , aber der größte Teil der Arbeit ist bereits erledigt. Verwenden wir Jacksons MapSerializer für unsere Karte und MyPairSerializer aus dem vorherigen Abschnitt für die Schlüssel- und Werttypen der Karte:

@JsonSerialize(keyUsing = MapSerializer.class) Map map; @JsonSerialize(keyUsing = MyPairSerializer.class) MyPair mapKey; @JsonSerialize(keyUsing = MyPairSerializer.class) MyPair mapValue;

Testen wir die Serialisierung unserer Karte :

mapKey = new MyPair("Abbott", "Costello"); mapValue = new MyPair("Comedy", "1940s"); map.put(mapKey, mapValue); String jsonResult = mapper.writerWithDefaultPrettyPrinter() .writeValueAsString(map);

Die serialisierte JSON-Ausgabe mit der toString () -Methode von MyPair lautet:

{ "Abbott and Costello" : "Comedy and 1940s" }

4. Deserialisierung

Die Deserialisierung konvertiert einen Bytestrom in ein Java-Objekt, das wir im Code verwenden können. In diesem Abschnitt werden wir JSON Eingang in deserialisieren Map s verschiedenen Signaturen.

4.1. Karten- Deserialisierung

Nehmen wir für den einfachen Fall eine JSON-formatierte Eingabezeichenfolge und konvertieren Sie sie in eine Map Java-Sammlung:

String jsonInput = "{\"key\": \"value\"}"; TypeReference
    
      typeRef = new TypeReference
     
      () {}; Map map = mapper.readValue(jsonInput, typeRef);
     
    

Wir verwenden Jackson ObjectMapper , wie wir für die Serialisierung taten, mit Readvalue () um die Eingabe zu verarbeiten. Beachten Sie auch, unsere Verwendung von Jacksons TypeReference , die wir in allen unseren Deserialisierung Beispiele verwenden werden, die Art der unser Ziel zu beschreiben Karte . Hier ist die toString () - Darstellung unserer Karte:

{key=value}

4.2. Karten- Deserialisierung

Ändern wir nun unseren Eingabe-JSON und die TypeReference unseres Ziels in Map :

String jsonInput = "{\"Abbott and Costello\" : \"Comedy\"}"; TypeReference
    
      typeRef = new TypeReference
     
      () {}; Map map = mapper.readValue(jsonInput, typeRef);
     
    

Wir müssen einen Konstruktor für MyPair erstellen , der einen String mit beiden Elementen verwendet und diese in die MyPair- Elemente analysiert :

public MyPair(String both) { String[] pairs = both.split("and"); this.first = pairs[0].trim(); this.second = pairs[1].trim(); }

And the toString() of our Map object is:

{Abbott and Costello=Comedy}

There is another option for the case when we deserialize into a Java class that contains a Map — we can use Jackson's KeyDeserializer class, one of many Deserialization classes that Jackson offers. We annotate our ClassWithAMap with @JsonCreator, @JsonProperty, and @JsonDeserialize:

public class ClassWithAMap { @JsonProperty("map") @JsonDeserialize(keyUsing = MyPairDeserializer.class) private Map map; @JsonCreator public ClassWithAMap(Map map) { this.map = map; } // public getters/setters omitted }

We are telling Jackson to deserialize the Map contained in ClassWithAMap, so we need to extend KeyDeserializer to describe how to deserialize the map's key, a MyPair object, from an input String:

public class MyPairDeserializer extends KeyDeserializer { @Override public MyPair deserializeKey( String key, DeserializationContext ctxt) throws IOException, JsonProcessingException { return new MyPair(key); } }

Wir testen die Deserialisierung mit readValue :

String jsonInput = "{\"Abbott and Costello\":\"Comedy\"}"; ClassWithAMap classWithMap = mapper.readValue(jsonInput, ClassWithAMap.class);

Auch hier liefert die toString () -Methode unserer ClassWithAMap- Map die erwartete Ausgabe:

{Abbott and Costello=Comedy}

4.3. Karten- Deserialisierung

Zuletzt ändern wir unseren Eingabe-JSON und die TypeReference unseres Ziels in Map :

String jsonInput = "{\"Abbott and Costello\" : \"Comedy and 1940s\"}"; TypeReference
    
      typeRef = new TypeReference
     
      () {}; Map map = mapper.readValue(jsonInput, typeRef);
     
    

Und das toString () unseres Map- Objekts lautet:

{Abbott and Costello=Comedy and 1940s}

5. Schlussfolgerung

In diesem kurzen Tutorial haben wir gesehen, wie Java Maps zu und von JSON-formatierten Strings serialisiert und deserialisiert werden .

Wie immer können Sie das in diesem Artikel bereitgestellte Beispiel im GitHub-Repository überprüfen.