Serialisierung und Deserialisierung mit Jackson zuordnen

Kartenserialisierung und Deserialisierung mit Jackson

1. Überblick

In diesem Artikel sehen wir unsserialization and deserialization of Java maps using Jackson an.

Wir werden veranschaulichen, wieMap<String, String>,Map<Object, String>, undMap<Object, Object> zu und von JSON-formatiertenStrings. serialisiert und deserialisiert werden

2. Maven-Konfiguration


    com.fasterxml.jackson.core
    jackson-databind
    2.9.4

Sie können die neueste Version von Jacksonhere erhalten.

3. Serialisierung

Durch die Serialisierung wird ein Java-Objekt in einen Bytestrom konvertiert, der bei Bedarf beibehalten oder gemeinsam genutzt werden kann. JavaMaps sind Sammlungen, die einen SchlüsselObject einem WertObject zuordnen und häufig die am wenigsten intuitiven Objekte sind, die serialisiert werden müssen.

3.1. Map<String, String> Serialisierung

Für den einfachen Fall erstellen wir einMap<String, String> und serialisieren es 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 unseremap serialisieren und als hübsch gedruckte JSONString mit dertoString()-Methode inStringausschreiben können. s:

{
  "key" : "value"
}

3.2. Map<Object, String> Serialisierung

Sie können eine Map, die eine benutzerdefinierte Java-Klasse enthält, mit ein paar zusätzlichen Schritten serialisieren. Erstellen wir eineMyPair-Klasse, um ein Paar verwandterString-Objekte darzustellen.

Hinweis: Die Getter / Setter sollten öffentlich sein, und wir kommentierentoString() mit@JsonValue, um sicherzustellen, dass Jackson diese benutzerdefiniertentoString() beim Serialisieren 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 erMyPair serialisiert, indem er JacksonsJsonSerializer 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 serialisiert, wie der Name schon sagt,MyPair mit der MethodetoString()vonMyPair nach JSON. Jackson bietet vieleSerializer classes, um Ihren Serialisierungsanforderungen zu entsprechen.

Wir wendenMyPairSerializer auf unsereMap<MyPair, String> mit der Annotation@JsonSerialize an. Beachten Sie, dass wir Jackson nur gesagt haben, wieMyPair serialisiert werden sollen, da er bereits weiß, wieString: serialisiert werden

@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. Map<Object, Object> Serialisierung

Der komplexeste Fall ist die Serialisierung vonMap<Object, Object>, aber der größte Teil der Arbeit ist bereits erledigt. Verwenden wir JacksonsMapSerializer für unsere Karte undMyPairSerializer 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 unsererMap<MyPair, MyPair>:

mapKey = new MyPair("Abbott", "Costello");
mapValue = new MyPair("Comedy", "1940s");
map.put(mapKey, mapValue);

String jsonResult = mapper.writerWithDefaultPrettyPrinter()
  .writeValueAsString(map);

Die serialisierte JSON-Ausgabe unter Verwendung dertoString()-Methode vonMyPairlautet:

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

4. Deserialisierung

Die Deserialisierung konvertiert einen Datenstrom von Bytes in ein Java-Objekt, das wir im Code verwenden können. In diesem Abschnitt deserialisieren wir die JSON-Eingabe inMaps unterschiedlicher Signaturen.

4.1. Map<String, String> Deserialisierung

Nehmen wir für den einfachen Fall eine JSON-formatierte Eingabezeichenfolge und konvertieren Sie sie in die Java-SammlungMap<String, String>:

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

Wir verwenden JacksonsObjectMapper wie für die Serialisierung und verwendenreadValue(), um die Eingabe zu verarbeiten. Beachten Sie auch unsere Verwendung von JacksonsTypeReference, die wir in all unseren Deserialisierungsbeispielen verwenden werden, um den Typ unseres ZielsMap zu beschreiben. Hier ist die Darstellung unserer Karte intoString():

{key=value}

4.2. Map<Object, String> Deserialisierung

Ändern wir nun unseren Eingabe-JSON und dieTypeReference unseres Ziels inMap<MyPair, String>:

String jsonInput = "{\"Abbott and Costello\" : \"Comedy\"}";

TypeReference> typeRef
  = new TypeReference>() {};
Map map = mapper.readValue(jsonInput, typeRef);

Wir müssen einen Konstruktor fürMyPair erstellen, der mit beiden Elementen einString nimmt und sie in dieMyPair-Elemente analysiert:

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

Und dietoString() unseresMap<MyPair,String>-Objekts sind:

{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, eine von vielenDeserialization Klassen, die Jackson anbietet. Wir kommentieren unsereClassWithAMap mit@JsonCreator,@JsonProperty und@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
}

Wir fordern Jackson auf, die inClassWithAMap enthaltenenMap<MyPair, String> zu deserialisieren. Daher müssen wirKeyDeserializer erweitern, um zu beschreiben, wie der Schlüssel der Karte, einMyPair-Objekt, aus einer Eingabe deserialisiert wird 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 mitreadValue:

String jsonInput = "{\"Abbott and Costello\":\"Comedy\"}";

ClassWithAMap classWithMap = mapper.readValue(jsonInput,
  ClassWithAMap.class);

Wiederum liefert dietoString()-Methode unsererClassWithAMap’s-Karte die erwartete Ausgabe:

{Abbott and Costello=Comedy}

4.3. Map<Object,Object> Deserialisierung

Zuletzt ändern wir unseren Eingabe-JSON und dieTypeReference unseres Ziels inMap<MyPair, MyPair>:

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

Und dietoString() unseresMap<MyPair, MyPair>-Objekts sind:

{Abbott and Costello=Comedy and 1940s}

5. Fazit

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

Wie immer können Sie das in diesem Artikel bereitgestellte Beispiel inGithub repository überprüfen.