Jackson 允许以多种不同方式注册自定义序列化程序。其中之一是使用com.fasterxml.jackson.databind.ser.BeanSerializerModifier 类,它允许创建自定义序列化器,但如果需要,我们也可以使用那里可用的基本序列化器。
上面的问题看起来像是OOP 问题的一个很好的例子,我们可以解耦POJO,它是逻辑和序列化过程。序列化器不应该知道如何将对象转换为Map。它应该只有序列化逻辑。下面介绍POJO和serialiser使用的接口:
interface Flattenable {
boolean isFlattened();
Map<String, Object> flatten();
}
class Foo implements Flattenable {
private boolean flattened;
private int id;
public Foo(boolean flattened, int id) {
this.flattened = flattened;
this.id = id;
}
@Override
public Map<String, Object> flatten() {
Map<String, Object> map = new LinkedHashMap<>();
map.put("id", getId());
map.put("random", ThreadLocalRandom.current().nextDouble());
return map;
}
@Override
public boolean isFlattened() {
return flattened;
}
public void setFlattened(boolean flattened) {
this.flattened = flattened;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
现在,我们可以通过实现Flattenable 接口轻松处理其他类型。序列化逻辑将是相同的。自定义序列化器可能如下所示:
class FlattenableJsonSerializer extends JsonSerializer<Flattenable> {
private final JsonSerializer<Object> base;
public FlattenableJsonSerializer(JsonSerializer base) {
this.base = Objects.requireNonNull(base);
}
@Override
public void serialize(Flattenable value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
if (value.isFlattened()) {
gen.writeObject(value.flatten());
} else {
base.serialize(value, gen, serializers);
}
}
}
当我们有POJO 模型和序列化器时,我们只需要配置ObjectMapper 并尝试使用我们的解决方案:
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ThreadLocalRandom;
public class JsonFlattenApp {
public static void main(String[] args) throws Exception {
SimpleModule flattenModule = new SimpleModule("FlattenModule");
flattenModule.setSerializerModifier(new FlattenableBeanSerializerModifier());
ObjectMapper mapper = JsonMapper.builder()
.addModule(flattenModule)
.build();
System.out.println(mapper.writeValueAsString(new Foo(true, 1)));
System.out.println(mapper.writeValueAsString(new Foo(false, 2)));
}
}
class FlattenableBeanSerializerModifier extends BeanSerializerModifier {
@Override
public JsonSerializer<?> modifySerializer(SerializationConfig config, BeanDescription beanDesc, JsonSerializer<?> serializer) {
if (Flattenable.class.isAssignableFrom(beanDesc.getBeanClass())) {
return new FlattenableJsonSerializer(serializer);
}
return serializer;
}
}
上面的代码打印了两行:
//1
{"id":1,"random":0.7818309762014325}
//2
{"flattened":false,"id":2}