Jackson ObjectMapper在调用WriteValueasString时不使用自定义[DE]序列化器

发布于 2025-01-29 10:18:28 字数 3927 浏览 2 评论 0原文

我的总体目标是将“零”列表备案化并序列化为空列表。 因此,使用变量 list foo 创建一个带有空值的类,最终将设置为空列表。 将对象编写为JSON时也是如此。如果 list foo 为null,则我需要将其写成{“ foo”:[]}。

但是,无论我尝试什么,我的ObjectMapper都不认识我正在做的任何事情。

相关类

@ApiModel(description = "A rule project.")
@JsonPropertyOrder({
    Project.JSON_PROPERTY_NAME
    Project.JSON_PROPERTY_CONSTANTS
})
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaJerseyServerCodegen", date = "2022-05-17T09:06:04.105050+02:00[Europe/Berlin]")
public class Project   {
    public static final String JSON_PROPERTY_NAME = "name";
    @JsonProperty(JSON_PROPERTY_NAME)
    private String name;

    public Project name(String name) {
        this.name = name;
        return this;
    }

    @JsonDeserialize(contentUsing = CountryDeserializer.class)
    @JsonSerialize(contentUsing = ListSerializer.class)
    private List<Constant> constants = null;

    @JsonDeserialize(contentUsing = CountryDeserializer.class)
    @JsonSerialize(contentUsing = ListSerializer.class)
    public List<Constant> getConstants() {
        return constants;
    }

    @JsonDeserialize(contentUsing = CountryDeserializer.class)
    @JsonSerialize(contentUsing = ListSerializer.class)
    public void setConstants(List<Constant> constants) {
        this.constants = constants;
    }

[de]序列化

public class CountryDeserializer extends JsonDeserializer<Constant> {

    @Override
    public Constant deserialize(JsonParser p, DeserializationContext ctxt, Constant intoValue) throws IOException {
        // TODO Auto-generated method stub
        return super.deserialize(p, ctxt, intoValue);
    }

    @Override
    public Object deserializeWithType(JsonParser p, DeserializationContext ctxt, TypeDeserializer typeDeserializer)
                    throws IOException {
        // TODO Auto-generated method stub
        return super.deserializeWithType(p, ctxt, typeDeserializer);
    }

    @Override
    public Object deserializeWithType(JsonParser p, DeserializationContext ctxt, TypeDeserializer typeDeserializer,
        Constant intoValue) throws IOException {
        // TODO Auto-generated method stub
        return super.deserializeWithType(p, ctxt, typeDeserializer, intoValue);
    }

    @Override
    public Constant deserialize(final JsonParser jp, final DeserializationContext ctxt) throws IOException {
        return null;
    }
}

public class ListSerializer extends JsonSerializer<List> {

    @Override
    public void serializeWithType(List value, JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer)
                    throws IOException {
        // TODO Auto-generated method stub
        super.serializeWithType(value, gen, serializers, typeSer);
    }

    @Override
    public void serialize(List value, JsonGenerator jgen, SerializerProvider provider)
                    throws IOException, JsonProcessingException {

        if (null == value) {
            provider.defaultSerializeValue(new ArrayList<Object>(), jgen);
        } else {
            provider.defaultSerializeValue(value, jgen);
        }
    }
}

我尝试的事情: 如您所见,我尝试注释字段,getters和setters以使用我的自定义序列化器,但是ObjectMapper从未使用过它们(通过设置断点)。

我还尝试使用各种选项配置对象映射器本身:

public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper()
        .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
        .setDefaultSetterInfo(JsonSetter.Value.forContentNulls(Nulls.AS_EMPTY))
        .setDefaultSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY));

或通过将[de]序列化器注册为简单模块,

SimpleModule module = new SimpleModule();
module.addDeserializer(List.class, new ListDeserializer());
objectMapper.registerModule(module);

但没有任何可行,这很奇怪。

我正在使用Jackson-Databind版本2.12.3

知道这里发生了什么?

My overall goal is to have "null" lists deserialized and serialized as empty lists.
So creating a class with the variable List foo with a null value, will finally be set as the empty list.
The same when writing the object as json. If List foo is null, I need it written as {"foo": []}.

But, no matter what I try, my objectmapper does not recognize any of the things I am doing.

Relevant class

@ApiModel(description = "A rule project.")
@JsonPropertyOrder({
    Project.JSON_PROPERTY_NAME
    Project.JSON_PROPERTY_CONSTANTS
})
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaJerseyServerCodegen", date = "2022-05-17T09:06:04.105050+02:00[Europe/Berlin]")
public class Project   {
    public static final String JSON_PROPERTY_NAME = "name";
    @JsonProperty(JSON_PROPERTY_NAME)
    private String name;

    public Project name(String name) {
        this.name = name;
        return this;
    }

    @JsonDeserialize(contentUsing = CountryDeserializer.class)
    @JsonSerialize(contentUsing = ListSerializer.class)
    private List<Constant> constants = null;

    @JsonDeserialize(contentUsing = CountryDeserializer.class)
    @JsonSerialize(contentUsing = ListSerializer.class)
    public List<Constant> getConstants() {
        return constants;
    }

    @JsonDeserialize(contentUsing = CountryDeserializer.class)
    @JsonSerialize(contentUsing = ListSerializer.class)
    public void setConstants(List<Constant> constants) {
        this.constants = constants;
    }

[De]serializers

public class CountryDeserializer extends JsonDeserializer<Constant> {

    @Override
    public Constant deserialize(JsonParser p, DeserializationContext ctxt, Constant intoValue) throws IOException {
        // TODO Auto-generated method stub
        return super.deserialize(p, ctxt, intoValue);
    }

    @Override
    public Object deserializeWithType(JsonParser p, DeserializationContext ctxt, TypeDeserializer typeDeserializer)
                    throws IOException {
        // TODO Auto-generated method stub
        return super.deserializeWithType(p, ctxt, typeDeserializer);
    }

    @Override
    public Object deserializeWithType(JsonParser p, DeserializationContext ctxt, TypeDeserializer typeDeserializer,
        Constant intoValue) throws IOException {
        // TODO Auto-generated method stub
        return super.deserializeWithType(p, ctxt, typeDeserializer, intoValue);
    }

    @Override
    public Constant deserialize(final JsonParser jp, final DeserializationContext ctxt) throws IOException {
        return null;
    }
}

public class ListSerializer extends JsonSerializer<List> {

    @Override
    public void serializeWithType(List value, JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer)
                    throws IOException {
        // TODO Auto-generated method stub
        super.serializeWithType(value, gen, serializers, typeSer);
    }

    @Override
    public void serialize(List value, JsonGenerator jgen, SerializerProvider provider)
                    throws IOException, JsonProcessingException {

        if (null == value) {
            provider.defaultSerializeValue(new ArrayList<Object>(), jgen);
        } else {
            provider.defaultSerializeValue(value, jgen);
        }
    }
}

Things I tried:
As you can see I tried to annotate the fields, getters and setters to use my custom serializers, but the objectmapper never uses them (tried by setting breakpoints).

I also tried to configure the object mapper itself with various options:

public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper()
        .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
        .setDefaultSetterInfo(JsonSetter.Value.forContentNulls(Nulls.AS_EMPTY))
        .setDefaultSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY));

Or by registering the [de]serializers as SimpleModule

SimpleModule module = new SimpleModule();
module.addDeserializer(List.class, new ListDeserializer());
objectMapper.registerModule(module);

But nothing works, it's just weird.

I am using jackson-databind version 2.12.3

Any idea what is going on here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文