JsonInclude.Include.NON_DEFAULT不适用于自定义序列化程序 [英] JsonInclude.Include.NON_DEFAULT not working with custom serializer

查看:1524
本文介绍了JsonInclude.Include.NON_DEFAULT不适用于自定义序列化程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆