杰克逊反序列化器 - 将空集合更改为空集合

时间:2015-09-04 13:08:17

标签: java json jackson

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

public class Entity {

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

}

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

{
  "homes": null
}

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

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. 如果第一点没有 - 我是否需要为此编写解串器?如果是的话,我可以写一般的吗?

3 个答案:

答案 0 :(得分:12)

从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和对unit tests的检查。 YMMV。

答案 1 :(得分:8)

我也找不到杰克逊的财产或注释。所以我不得不回答第一个问题。但我建议使用简单的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,因为杰克逊会关联setHomeshomes

答案 2 :(得分:0)

对我有用的只是删除setter并使属性最终。杰克逊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