杰克逊-结合@JsonValue和@JsonSerialize

约翰·达皮

我想要的组合@JsonValue@JsonSerialize让我们从我当前的容器类开始:

public class Container {
    private final Map<SomeKey, Object> data;

    @JsonValue
    @JsonSerialize(keyUsing = SomeKeySerializer.class)
    public Map<SomeKey, Object> data() {
        return data;
    }
}

在这种情况下,SomeKeySerializer不使用自定义序列化程序。

如果按以下方式更改容器,则调用序列化器:

public class Container {
    @JsonSerialize(keyUsing = SomeKeySerializer.class)
    private final Map<SomeKey, Object> data;
}

但是,这不是我想要的,因为这在输出JSON中引入了另一个“数据”级别。

是否有可能结合起来@JsonValue,并@JsonSerialize以某种方式?

我总是可以为其编写另一个自定义序列化程序Container,该序列化程序的功能或多或少地与后面的功能相同@JsonValue我认为,这或多或少是一个hack。

杰克逊版本:2.6.2

阿拉克尼德

这种组合似乎可以满足您的要求:创建一个Converter以从Container中提取Map,然后将@JsonValue添加到SomeKey本身以对其进行序列化:

@JsonSerialize(converter = ContainerToMap.class)
public class ContainerWithFieldData {
    private final Map<SomeKey, Object> data;

    public ContainerWithFieldData(Map<SomeKey, Object> data) {
        this.data = data;
    }
}

public static final class SomeKey {
    public final String key;

    public SomeKey(String key) {
        this.key = key;
    }

    @JsonValue
    public String toJsonValue() {
        return "key:" + key;
    }

    @Override
    public String toString() {
        return "SomeKey:" + key;
    }
}

public static final class ContainerToMap extends StdConverter<ContainerWithFieldData, Map<SomeKey, Object>> {
    @Override
    public Map<SomeKey, Object> convert(ContainerWithFieldData value) {
        return value.data;
    }
}

@Test
public void serialize_container_with_custom_keys_in_field_map() throws Exception {
    ObjectMapper mapper = new ObjectMapper();
    assertThat(
            mapper.writeValueAsString(new ContainerWithFieldData(ImmutableMap.of(new SomeKey("key1"), "value1"))),
            equivalentTo("{ 'key:key1' : 'value1' }"));
}

我根本无法轻松地将容器的访问器方法注释为DTRT,而不是与@JsonValue结合使用。鉴于容器上的@JsonValue基本上是在指定转换器(通过调用带注释的方法实现),这实际上是您所追求的,尽管看起来并不愉快。(与杰克逊2.6.2一起尝试)

(我从中学到的东西:密钥序列化器与普通序列化器不同,即使它们实现JsonSerializer的方式相同。例如,它们需要在JsonGenerator而不是writeString上调用writeFieldName。在反序列化方面,JsonDeserializer和KeyDeserializer是详细说明的,但不是在序列化方面的,您可以使用@JsonValue从SomeKey进行密钥序列化,但是不能通过@JsonSerialize(using = ...)注释SomeKey,这让我感到惊讶。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章