ジャクソン - 地図とnullの取り扱い

ジャクソン–マップとnullの操作

1. 概要

この簡単な記事では、Jackson – working with Maps that contain null values or null keysを使用するより高度なユースケースを見ていきます。

2. マップ内のNull値を無視する

ジャクソンには、Mapがシリアル化されたときにnull値がどうなるかをグローバルに制御するシンプルで便利な方法があります。

ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(Include.NON_NULL);

これで、このマッパーを介してシリアル化されたMapオブジェクトのnull値は無視されます。

@Test
public void givenIgnoringNullValuesInMap_whenWritingMapObjectWithNullValue_thenIgnored()
  throws JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();
    mapper.setSerializationInclusion(Include.NON_NULL);

    MyDto dtoObject1 = new MyDto();

    Map dtoMap = new HashMap();
    dtoMap.put("dtoObject1", dtoObject1);
    dtoMap.put("dtoObject2", null);

    String dtoMapAsString = mapper.writeValueAsString(dtoMap);

    assertThat(dtoMapAsString, containsString("dtoObject1"));
    assertThat(dtoMapAsString, not(containsString("dtoObject2")));
}

3. ヌルキーを使用したマップのシリアル化

デフォルトでは、Jackson doesn’t allow the serialization of a Map with a null keyです。 このようなマップを書き出そうとすると、次の例外が発生します。

c.f.j.c.JsonGenerationException:
  Null key for a Map not allowed in JSON (use a converting NullKeySerializer?)
    at c.f.j.d.s.i.FailingSerializer.serialize(FailingSerializer.java:36)

ただし、ライブラリは十分に柔軟性があるため、a custom, null key serializerを定義して、デフォルトの動作を上書きできます。

class MyDtoNullKeySerializer extends StdSerializer {
    public MyDtoNullKeySerializer() {
        this(null);
    }

    public MyDtoNullKeySerializer(Class t) {
        super(t);
    }

    @Override
    public void serialize(Object nullKey, JsonGenerator jsonGenerator, SerializerProvider unused)
      throws IOException, JsonProcessingException {
        jsonGenerator.writeFieldName("");
    }
}


これで、nullキーを持つMapは正常に機能します。nullキーは空の文字列として書き込まれます。

@Test
public void givenAllowingMapObjectWithNullKey_whenWriting_thenCorrect()
throws JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();
    mapper.getSerializerProvider().setNullKeySerializer(new MyDtoNullKeySerializer());

    MyDto dtoObject = new MyDto();
    dtoObject.setStringValue("dtoObjectString");

    Map dtoMap = new HashMap();
    dtoMap.put(null, dtoObject);

    String dtoMapAsString = mapper.writeValueAsString(dtoMap);

    assertThat(dtoMapAsString, containsString("\"\""));
    assertThat(dtoMapAsString, containsString("dtoObjectString"));
}

4. ヌルフィールドを無視する

マップに加えて、Jacksonは、一般にnullフィールドを無視/操作するための多くの構成と柔軟性を提供します。 this tutorialをチェックして、それがどのように機能するかを正確に確認できます。

5. 結論

Mapオブジェクトのシリアル化は十分に一般的であるため、シリアル化プロセスの微妙な違いを適切に処理できるライブラリが必要です。 ジャクソンは、このシリアル化プロセスの出力を非常にうまく形作るのに役立ついくつかの便利なカスタマイズオプションを提供しています。

また、より一般的な意味でa lot of solid ways to work with collectionsを提供します。

これらすべての例とコードスニペットcan be found in over on GitHubの実装–これはMavenベースのプロジェクトであるため、そのままインポートして実行するのは簡単です。