There are a couple of ways to achieve custom null value serialising:
If you want to serialise a null as an empty String, try using this annotation on a property, or setter:
@JsonSetter(nulls=Nulls.AS_EMPTY)
or the same for specific mapper:
MAPPER.configOverride(String.class).setSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY));
- You can initialise properties with default values on the declaration or in the getter.
- As you've already mentioned, by providing a custom serialiser.
I did try your code, and that serialised null value as expected when using an ObjectMapper instead of JodaMapper. Is there any particular reason for using a JodaMapper?
Answer from Dmytro Rybachok on Stack OverflowThere are a couple of ways to achieve custom null value serialising:
If you want to serialise a null as an empty String, try using this annotation on a property, or setter:
@JsonSetter(nulls=Nulls.AS_EMPTY)
or the same for specific mapper:
MAPPER.configOverride(String.class).setSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY));
- You can initialise properties with default values on the declaration or in the getter.
- As you've already mentioned, by providing a custom serialiser.
I did try your code, and that serialised null value as expected when using an ObjectMapper instead of JodaMapper. Is there any particular reason for using a JodaMapper?
I found the solution.... I had
@JsonInclude(JsonInclude.Include.NON_NULL)
at class level in the class that I wanted to serialize. When I remove the annotation I the code above works.
After looking through documentation I found that Jackson uses nullsUsing parameter in JsonSerialize. So for example:
@JsonSerialize(nullsUsing = NullMapSerializer.class)
private Map<String, String> map;
I defined different serializers like so:
public class NullMapSerializer extends JsonSerializer<Map> {
@Override
public void serialize(
final Map value,
final JsonGenerator jsonGenerator,
final SerializerProvider serializerProvider
) throws IOException {
jsonGenerator.writeStartObject();
jsonGenerator.writeEndObject();
}
}
public class NullListSerializer extends JsonSerializer<List> {
@Override
public void serialize(
final List list,
final JsonGenerator jsonGenerator,
final SerializerProvider serializerProvider
) throws IOException {
jsonGenerator.writeStartArray();
jsonGenerator.writeEndArray();
}
}
public class NullStringSerializer extends JsonSerializer<String> {
@Override
public void serialize(
final String value,
final JsonGenerator jsonGenerator,
final SerializerProvider serializerProvider
) throws IOException {
jsonGenerator.writeString(StringUtils.EMPTY);
}
}
This serializes fields into {}, [], or "" whenever values are null, and normally otherwise.
If you want to have a general method for any object, there can be used the following:
public class NullObjectSerializer extends JsonSerializer<Object> {
@Override
public void serialize(Object action, JsonGenerator generator, SerializerProvider provider) throws IOException {
generator.writeString(StringUtils.EMPTY);
}
}
And the field will be marked:
@JsonSerialize(nullsUsing = NullObjectSerializer.class)
private MyEnum enumField;
You have the annotation in the wrong place - it needs to be on the class, not the field. i.e:
@JsonInclude(Include.NON_NULL) //or Include.NON_EMPTY, if that fits your use case
public static class Request {
// ...
}
As noted in comments, in versions below 2.x the syntax for this annotation is:
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) // or JsonSerialize.Inclusion.NON_EMPTY
The other option is to configure the ObjectMapper directly, simply by calling
mapper.setSerializationInclusion(Include.NON_NULL);
(for the record, I think the popularity of this answer is an indication that this annotation should be applicable on a field-by-field basis, @fasterxml)
You can also set the global option:
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);