gpt4 book ai didi

java - JsonInclude.Include.NON_DEFAULT 不适用于自定义序列化程序

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:39:11 27 4
gpt4 key购买 nike

我既想使用自定义序列化程序,又想使用 JsonInclude.Include.NON_DEFAULT 指定。当我不使用自定义序列化程序时,它很荣幸,但当我使用自定义序列化程序时,它不是。

这是 jackson 2.2.2。我目前没有切换到更新版本的 Jackson 的选项。

这是一个显示问题的简单示例:

import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

import java.io.IOException;
import java.util.EnumSet;
import java.util.Set;
import java.util.stream.Collectors;

public class JacksonSerialization
{
public static void main(String[] args) throws Exception {
ObjectMapper serializer = new ObjectMapper();

Foo foo = new Foo();
foo.setFlags(EnumSet.of(Flag.CC, Flag.BB));
System.out.println(serializer.writeValueAsString(foo));

foo = new Foo();
System.out.println(serializer.writeValueAsString(foo));
}

public static enum Flag
{
AA,
BB,
CC
}

@JsonInclude(JsonInclude.Include.NON_DEFAULT)
public static class Foo
{
private Set<Flag> flags;

public Foo() {
flags = EnumSet.of(Flag.AA);
}

@JsonGetter("f")
@JsonSerialize(using = FlagSetSerializer.class)
public Set<Flag> getFlags() {
return flags;
}

public void setFlags(Set<Flag> theFlags) {
flags = theFlags;
}
}

public static class FlagSetSerializer extends JsonSerializer<Set<Flag>>
{
@Override
public void serialize(Set<Flag> value,
JsonGenerator jsonGenerator,
SerializerProvider serializerProvider) throws IOException {
String csv = value.stream()
.map(Flag::toString)
.collect(Collectors.joining(","));
jsonGenerator.writeString(csv);
}
}
}

这是输出:

{"f":"BB,CC"}
{"f":"AA"}

请注意,即使 f 具有默认值,它也会被序列化。如果我注释掉 @JsonSerialize 注释,则会得到以下输出:

{"f":["BB","CC"]}
{}

然后f 正确地 得到序列化。但当然,事情并没有以我想要的格式序列化。

那么我如何获得自定义序列化程序以遵守类的 @JsonInclude 注释?

最佳答案

您可能希望根据 documentation 实现 public boolean isEmpty(SerializerProvider provider, T value) ,它说:

public boolean isEmpty(SerializerProvider provider, T value)

Method called to check whether given serializable value is considered "empty" value (for purposes of suppressing serialization of empty values).

Default implementation will consider only null values to be empty.

根据 https://github.com/FasterXML/jackson-databind/issues/730

另一个可能的麻烦来源是您谈论 NON_EMPTY 但您的代码使用 NON_DEFAULT


在调试器中深入挖掘导致我提出建议

@JsonSerialize(using = FlagSetSerializer.class, include = JsonSerialize.Inclusion.NON_DEFAULT)

这似乎通过了您的测试。

问题 似乎在 JacksonAnnotationInspector#findSerializationInclusion 中,它首先在属性上查找 @JsonInclude 属性,当它失败时要找到它,它会查找 @JsonSerialize 注释。 @JsonSerialize 包含一个已弃用的 include 属性,它的默认值为 ALWAYS

我没有深入研究它,但我怀疑弃用/重构设法切断了一些功能。 C'est la vie.

关于java - JsonInclude.Include.NON_DEFAULT 不适用于自定义序列化程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36288834/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com