1. 概要

このクイックチュートリアルでは、Jacksonを使用したJavaマップのシリアル化と逆シリアル化について説明します。

シリアル化と逆シリアル化の方法を説明します地図 地図地図 JSON形式の送受信文字列。

2. Maven構成

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.3</version>
</dependency>

ジャクソンの最新バージョンはこちらで入手できます。

3. シリアル化

シリアル化は、Javaオブジェクトをバイトのストリームに変換します。このストリームは、必要に応じて永続化または共有できます。 Java Maps は、キー Objectを値Object、にマップするコレクションであり、多くの場合、シリアル化するのに最も直感的でないオブジェクトです。

3.1. 地図シリアル化

簡単なケースとして、 地図そしてそれをJSONにシリアル化します:

Map<String, String> map = new HashMap<>();
map.put("key", "value");

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

ObjectMapper は、Jacksonのシリアル化マッパーです。 map、をシリアル化し、 StringtoString()メソッドを使用して、きれいに印刷されたJSON Stringとして書き出すことができます。 ]:

{
  "key" : "value"
}

3.2。 地図シリアル化

いくつかの追加手順で、カスタムJavaクラスを含むマップをシリアル化することもできます。 関連するStringオブジェクトのペアを表すMyPairクラスを作成しましょう。

注:ゲッター/セッターはパブリックである必要があり、 toString() @JsonValue のアノテーションを付けて、Jacksonがシリアル化時にこのカスタム toString()を使用するようにします。

public class MyPair {

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

次に、Jacksonの JsonSerializer を拡張して、MyPairをシリアル化する方法をJacksonに指示します。

public class MyPairSerializer extends JsonSerializer<MyPair> {

    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 は、その名前が示すように、 MyPairtoString()メソッドを使用してMyPairをJSONにシリアル化します。 さらに、Jacksonは、シリアル化の要件に合わせて、多くのSerializerクラスを提供しています。

次に適用します MyPairSerializer 私たちに地図とともに @JsonSerialize 注釈。 String:をシリアル化する方法をすでに知っているため、JacksonにMyPairをシリアル化する方法のみを説明したことに注意してください。

@JsonSerialize(keyUsing = MyPairSerializer.class) 
Map<MyPair, String> map;

次に、マップのシリアル化をテストしましょう。

map = new HashMap<>();
MyPair key = new MyPair("Abbott", "Costello");
map.put(key, "Comedy");

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

シリアル化されたJSON出力は次のとおりです。

{
  "Abbott and Costello" : "Comedy"
}

3.3. 地図シリアル化

最も複雑なケースは、シリアル化です。 地図 、しかし、ほとんどの作業はすでに完了しています。 マップにはJacksonのMapSerializerを使用し、マップのキーと値のタイプには前のセクションの MyPairSerializer、を使用してみましょう。

@JsonSerialize(keyUsing = MapSerializer.class)
Map<MyPair, MyPair> map;
	
@JsonSerialize(keyUsing = MyPairSerializer.class)
MyPair mapKey;

@JsonSerialize(keyUsing = MyPairSerializer.class)
MyPair mapValue;

次に、シリアル化をテストしてみましょう地図

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

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

MyPairtoString()メソッドを使用したシリアル化されたJSON出力は次のとおりです。

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

4. デシリアライズ

デシリアライズは、バイトのストリームをコードで使用できるJavaオブジェクトに変換します。 このセクションでは、JSON入力をさまざまな署名の Mapに逆シリアル化します。

4.1. 地図デシリアライズ

単純なケースとして、JSON形式の入力文字列を取得して次のように変換してみましょう。 地図 Javaコレクション:

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

シリアル化の場合と同様に、Jacksonの ObjectMapper、を使用し、 readValue()を使用して入力を処理します。 また、Jacksonの TypeReference の使用にも注意してください。これは、すべての逆シリアル化の例で、宛先Mapのタイプを説明するために使用します。 マップのtoString()表現は次のとおりです。

{key=value}

4.2. 地図デシリアライズ

次に、入力JSONと TypeReference 私たちの目的地の地図

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

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

MyPair のコンストラクターを作成する必要があります。このコンストラクターは、両方の要素を含む String を取得し、それらをMyPair要素に解析します。

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

The toString() 私たちの地図オブジェクトは次のとおりです。

{Abbott and Costello=Comedy}

マップを含むJavaクラスに逆シリアル化する場合の別のオプションがあります。 Jacksonが提供する多くのDeserializationクラスの1つであるJacksonのKeyDeserializerクラスを使用できます。 ClassWithAMap@JsonCreator @JsonProperty 、および @JsonDeserialize:で注釈を付けましょう。

public class ClassWithAMap {

  @JsonProperty("map")
  @JsonDeserialize(keyUsing = MyPairDeserializer.class)
  private Map<MyPair, String> map;

  @JsonCreator
  public ClassWithAMap(Map<MyPair, String> map) {
    this.map = map;
  }
 
  // public getters/setters omitted
}

ここでは、ジャクソンに逆シリアル化するように指示しています地図に含まれます ClassWithAMap 、拡張する必要があります KeyDeserializer マップのキーを逆シリアル化する方法を説明するには、 MyPair オブジェクト、入力から

public class MyPairDeserializer extends KeyDeserializer {

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

次に、readValueを使用して逆シリアル化をテストできます。

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

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

ここでも、ClassWithAMapのマップのtoString()メソッドは、期待する出力を提供します。

{Abbott and Costello=Comedy}

4.3. 地図デシリアライズ

最後に、入力JSONと TypeReference 私たちの目的地の地図

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

The toString() 私たちの地図オブジェクトは次のとおりです。

{Abbott and Costello=Comedy and 1940s}

5. 結論

この短い記事では、Java MapsをJSON形式の文字列との間でシリアル化および逆シリアル化する方法を学びました。

いつものように、この記事で提供されている例は、GitHubリポジトリで入手できます。