Jackson 反序列化器 - 将空集合更改为空集合

Jackson deserializer - change null collection to empty one

我有一个包含集合作为属性的实体:

public class Entity {

    @JsonProperty(value="homes")
    @JsonDeserialize(as=HashSet.class, contentAs=HomeImpl.class)
    private Collection<Home> homes = new ArrayList<Home>();

}

如果请求包含 null 作为请求 属性:

{
  "homes": null
}

然后将 homes 设置为 null。我想要做的是将 homes 设置为空列表。我需要为此编写特殊的反序列化器还是有一个用于集合?我尝试的是这个反序列化器,但它看起来很丑(它不是通用的,使用实现而不是接口)。

public class NotNullCollectionDeserializer extends JsonDeserializer<Collection<HomeImpl>> {

  @Override
  public Collection<HomeImpl> deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
    return jsonParser.readValueAs(new TypeReference<Collection<HomeImpl>>(){});
  }

  @Override
  public Collection<HomeImpl> getNullValue() {
    return Collections.emptyList();
  }
}

问题太少了:

  1. 是否有一些 jackson 属性 在反序列化期间将 null 更改为空集合?
  2. 如果第一点不是——我需要为此编写解串器吗?如果是,我可以写一个通用的吗?

我也找不到 Jackson 属性 或注释。所以我必须对第一个问题回答不。但我会推荐一个简单的 setter 而不是特殊的解串器:

public class Entity {

    @JsonDeserialize(contentAs = HomeImpl.class)
    private Collection<Home> homes = new ArrayList<>();

    public void setHomes(List<Home> homes) {
        if (homes != null)
            this.homes = homes;
    }
}

这是通用的,因为它只使用 Home 接口而不是 HomeImpl。您不需要 @JsonProperty,因为 Jackson 会关联 setHomeshomes

对我有用的是简单地删除 setter 并使属性成为最终属性。 jackson 2 然后将使用 getter 修改列表。

public class Entity {

  @JsonProperty(value="homes")
  @JsonDeserialize(as=HashSet.class, contentAs=HomeImpl.class)
  private final Collection<Home> homes = new ArrayList<Home>();

  public List<Home> getHomes() {
     return homes;
  }
}

负责的功能是 USE_GETTERS_AS_SETTERS,默认情况下打开:https://github.com/FasterXML/jackson-databind/wiki/Mapper-Features

从 Jackson 2.9 开始,似乎可以使用 @JsonSetter 配置特定属性的空值处理,例如:

@JsonSetter(nulls = Nulls.AS_EMPTY)
public void setStrings(List<String> strings) {
    this.strings = strings;
}

类似的配置也可以全局应用于集合:

ObjectMapper mapper = objectMapperBuilder()
    .changeDefaultNullHandling(n -> n.withContentNulls(Nulls.AS_EMPTY))
    .build();

或按类型:

ObjectMapper mapper = objectMapperBuilder()
    .withConfigOverride(List.class,
        o -> o.setNullHandling(JsonSetter.Value.forContentNulls(Nulls.AS_EMPTY)))
    .build();

我无法试用该功能,所以这是基于 feature discussion and examination of unit tests。 YMMV.