I am developing a REST interface for my app using Jackson to serialize my POJO domain objects to JSON representation. I want to customize the serialization for some types to
We can extend BeanSerializer
, but with little trick.
First, define a java class to wrapper your POJO.
@JsonSerialize(using = MixinResultSerializer.class)
public class MixinResult {
private final Object origin;
private final Map mixed = Maps.newHashMap();
@JsonCreator
public MixinResult(@JsonProperty("origin") Object origin) {
this.origin = origin;
}
public void add(String key, String value) {
this.mixed.put(key, value);
}
public Map getMixed() {
return mixed;
}
public Object getOrigin() {
return origin;
}
}
Then,implement your custom serializer
.
public final class MixinResultSerializer extends BeanSerializer {
public MixinResultSerializer() {
super(SimpleType.construct(MixinResult.class), null, new BeanPropertyWriter[0], new BeanPropertyWriter[0]);
}
public MixinResultSerializer(BeanSerializerBase base) {
super(base);
}
@Override
protected void serializeFields(Object bean, JsonGenerator gen, SerializerProvider provider) throws IOException {
if (bean instanceof MixinResult) {
MixinResult mixin = (MixinResult) bean;
Object origin = mixin.getOrigin();
BeanSerializer serializer = (BeanSerializer) provider.findValueSerializer(SimpleType.construct(origin.getClass()));
new MixinResultSerializer(serializer).serializeFields(origin, gen, provider);
mixin.getMixed().entrySet()
.stream()
.filter(entry -> entry.getValue() != null)
.forEach((entry -> {
try {
gen.writeFieldName(entry.getKey());
gen.writeRawValue(entry.getValue());
} catch (IOException e) {
throw new RuntimeException(e);
}
}));
} else {
super.serializeFields(bean, gen, provider);
}
}
}
This way, we can handle the case that origin object using jackson annotations to custom serialize behavior.