jackson objectmapper does not use custom [de]serializer when calling writeValueAsString

Viewed 91

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?

0 Answers
Related