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?