JsonInclude.Include.NON_DEFAULT不适用于自定义序列化程序 [英] JsonInclude.Include.NON_DEFAULT not working with custom serializer
问题描述
我既要使用自定义序列化程序,又要使用JsonInclude.Include.NON_DEFAULT
名称.当我不使用自定义序列化程序时,是很荣幸的,但是当我使用自定义序列化程序时,则不行.
I want to both use a custom serializer and have the JsonInclude.Include.NON_DEFAULT
designation be honored. When I don't use a custom serializer it is honored but when I do use a custom serializer it is not.
这是杰克逊2.2.2.我目前没有选择切换到较新版本的Jackson的选择.
This is Jackson 2.2.2. I do not presently have the option to switch to a newer version of Jackson.
这是一个显示问题的简单示例:
Here's a simple example that shows the problem:
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
批注,则会得到以下输出:
Note that f
is being serialized even when it has the default value. If I comment out the @JsonSerialize
annotation then I get the following output:
{"f":["BB","CC"]}
{}
然后f
正确地将 not 序列化.但是当然,事情并没有按照我想要的格式进行序列化.
Then f
properly does not get serialized. But of course things are not being serialized in the format I want.
那么我如何获得自定义序列化器来兑现该类的@JsonInclude
批注?
So how do I get the custom serializer to honor the class's @JsonInclude
annotation?
推荐答案
You probably want to implement public boolean isEmpty(SerializerProvider provider, T value)
as per the documentation, which says:
公共布尔isEmpty(SerializerProvider提供程序,T值)
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
.
Another possible source of trouble is that you talk about NON_EMPTY
but you code uses NON_DEFAULT
.
在调试器中进行的过多挖掘导致我提出建议
And rather too much digging in the debugger leads me to suggest
@JsonSerialize(using = FlagSetSerializer.class, include = JsonSerialize.Inclusion.NON_DEFAULT)
似乎通过了测试.
问题 似乎在JacksonAnnotationInspector#findSerializationInclusion
中,该问题首先在属性上寻找@JsonInclude
属性,当找不到该属性时,它将寻找@JsonSerialize
注释. @JsonSerialize
包括已弃用的include
属性,该属性的默认值为ALWAYS
.
The problem seems to be in JacksonAnnotationInspector#findSerializationInclusion
, which first looks for a @JsonInclude
attribute on the property, and when it fails to find that, it looks for a @JsonSerialize
annotation. @JsonSerialize
includes a deprecated include
property, which has a default value of ALWAYS
.
我还没有深入研究它,但是我怀疑弃用/重构成功地剥离了一些功能. C'est la vie.
I've not looked into it too deeply, but I suspect a deprecation/refactor managed to slice off some functionality. C'est la vie.
这篇关于JsonInclude.Include.NON_DEFAULT不适用于自定义序列化程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!