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.
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);
}
}
}
And here's the output:
{"f":"BB,CC"}
{"f":"AA"}
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"]}
{}
Then f
properly does not get serialized. But of course things are not being serialized in the format I want.
So how do I get the custom serializer to honor the class's @JsonInclude
annotation?