我想要使用自定义序列化程序并且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
注释?
答案 0 :(得分:2)
您可能希望根据documentation实施public boolean isEmpty(SerializerProvider provider, T value)
,其中包含:
public boolean isEmpty(SerializerProvider provider,T value)
调用方法以检查是否考虑给定的可序列化值 “空”值(用于抑制空序列化的目的) 值)。
默认实现仅考虑空值 空。
根据https://github.com/FasterXML/jackson-databind/issues/730
另一个可能的麻烦来源是您谈论NON_EMPTY
,但您的代码使用NON_DEFAULT
。
而在调试器中挖掘过多导致我建议
@JsonSerialize(using = FlagSetSerializer.class, include = JsonSerialize.Inclusion.NON_DEFAULT)
这似乎通过了你的考试。
问题似乎在JacksonAnnotationInspector#findSerializationInclusion
中,它首先在属性上查找@JsonInclude
属性,当它找不到该属性时,它会查找{ {1}}注释。 @JsonSerialize
包含已弃用的@JsonSerialize
属性,其默认值为include
。
我没有深入研究它,但我怀疑弃用/重构设法切断了一些功能。 C'est la vie。