我既想使用自定义序列化程序,又想使用 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/