Jackson – Working with Maps and nulls – Jackson – 使用地图和空值的工作

最后修改: 2015年 5月 31日

1. Overview

1.概述

In this quick article, we’re going to look at a more advanced use-case of using Jackson – working with Maps that contain null values or null keys.

在这篇简短的文章中,我们将看看使用Jackson的一个更高级的用例–处理包含空值或空键的Maps

2. Ignore Nulls Values in a Map

2.忽略地图中的空值

Jackson has a simple but useful way of globally controlling what happens to null values when a Map gets serialized:

Jackson有一个简单但有用的方法,可以全局控制当Map被序列化时空值的情况。

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

Now any null value in Map object serialized through this mapper is going to be ignored:

现在,通过这个映射器序列化的Map对象中的任何空值都将被忽略。

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

    MyDto dtoObject1 = new MyDto();

    Map<String, MyDto> dtoMap = new HashMap<String, MyDto>();
    dtoMap.put("dtoObject1", dtoObject1);
    dtoMap.put("dtoObject2", null);

    String dtoMapAsString = mapper.writeValueAsString(dtoMap);

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

3. Serializing a Map With a Null Key

3.序列化一个带有空键的地图

By default, Jackson doesn’t allow the serialization of a Map with a null key. If you do try to write out such a map, you’ll get the following exception:

默认情况下,Jackson不允许序列化一个空键的Map。如果你试图写出这样的地图,你会得到以下异常。

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)

The library is however flexible enough that you can define a custom, null key serializer and override the default behavior:

然而,该库足够灵活,你可以定义一个自定义的空键序列化器并覆盖默认行为。

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

    public MyDtoNullKeySerializer(Class<Object> t) {
        super(t);
    }
    
    @Override
    public void serialize(Object nullKey, JsonGenerator jsonGenerator, SerializerProvider unused) 
      throws IOException, JsonProcessingException {
        jsonGenerator.writeFieldName("");
    }
}

Now the Map with the null key will work just fine – and the null key will be written as an empty String:

现在,带有空键的Map就可以正常工作了–空键将被写成一个空的String。

@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<String, MyDto> dtoMap = new HashMap<String, MyDto>();
    dtoMap.put(null, dtoObject);

    String dtoMapAsString = mapper.writeValueAsString(dtoMap);

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

4. Ignore Null Fields

4.忽略空字段

Besides Maps, Jackson provides a lot of configuration and flexibility for ignoring/working with null fields in general. You can check out this tutorial to see exactly how that works.

除了Maps之外,Jackson还为忽略/处理一般的null字段提供了大量的配置和灵活性。您可以查看本教程以了解其具体工作原理。

5. Conclusion

5.结论

Serializing a Map object is common enough that we need a library that’s able to handle the nuances of the serialization process well. Jackson provides a few handy customization options to help you shape the output of this serialization process quite well.

序列化一个Map对象是很常见的,我们需要一个能够很好地处理序列化过程中的细微差别的库。Jackson提供了一些方便的自定义选项,帮助你很好地塑造这个序列化过程的输出。

It also provides a lot of solid ways to work with collections in a more general sense.

它还提供了很多可靠的方法来在更广泛的意义上处理集合

The implementation of all these examples and code snippets can be found in over on GitHub – this is a Maven-based project, so it should be easy to import and run as it is.

所有这些例子和代码片段的实现可以在GitHub上找到 – 这是一个基于Maven的项目,所以应该很容易导入并按原样运行。