【发布时间】:2020-04-20 06:53:49
【问题描述】:
我有一些特殊的业务让我需要一个自定义序列化器,它在修改 DictAnnotation 注释的字段中添加一个字段,它可以工作。
但是 @JsonFormat 不起作用。
我的 createTime 字段以前是这样的:
"createTime":"2019-12-12"
现在:
"createTime":1577835397615
DictAnnotation 没有修改的字段都使用了默认的JsonSerializer,所以不知道问题出在哪里。
我的主要代码如下:
绑定自定义SerializerModifier
@Bean
public Jackson2ObjectMapperBuilder objectMapperBuilder() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
SimpleModule simpleModule = new SimpleModule().setSerializerModifier(new DictSerializerModifier());
builder.modules(simpleModule);
return builder;
}
自定义 SerializerModifier
public class DictSerializerModifier extends Jdk8BeanSerializerModifier {
@Override
public JsonSerializer<?> modifySerializer(SerializationConfig config, BeanDescription beanDesc, JsonSerializer<?> serializer) {
return new DictSerializer(null, (JsonSerializer<Object>) serializer);
}
}
自定义序列化器
public class DictSerializer extends JsonSerializer<Object> implements ContextualSerializer {
private static final String MY_BIZ_FIELD_SUFFIX = "_test";
private DictAnnotation.ElementType type;
private JsonSerializer<Object> defSerializer;
public DictSerializer(DictAnnotation.ElementType type, JsonSerializer<Object> jsonSerializer) {
this.defSerializer = jsonSerializer;
this.type = type;
}
@Override
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) {
// my biz annotation
DictAnnotation.ElementType elementType = Optional.ofNullable(property).map(b -> b.getAnnotation(DictAnnotation.class))
.map(d -> d.type()).orElse(null);
// if null, use defSerializer
return elementType == null ? defSerializer : new DictSerializer(elementType, defSerializer);
}
@Override
public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
defSerializer.serialize(value, gen, serializers);
if (type != null) {
String fieldName = gen.getOutputContext().getCurrentName();
String codeLabel = RedisUtils.dictCodeToLabel(type, value.toString());
gen.writeStringField(fieldName.concat(MY_BIZ_FIELD_SUFFIX), codeLabel);
}
}
}
测试pojo类
public class TestVo {
@DictAnnotation(type = A)
private String aCode;
@DictAnnotation(type = B)
private String bCode;
@DictAnnotation(type = C)
private String cCode;
@JsonFormat(pattern="yyyy-MM-dd",timezone = "GMT+8")
private Date createTime;
getter.... settter...
期待您的指导!
【问题讨论】:
-
为什么要扩展
Jdk8BeanSerializerModifier?你可以试试com.fasterxml.jackson.databind.ser.BeanSerializerModifier吗?也许Jdk8BeanSerializerModifier做的比你想要的多。 -
您是否在 Spring Boot 1.X 中将
TestVo作为带有@ResponseBody的 HTTP 响应返回? -
@Michał Ziober 尝试后,效果是一样的。看来Jdk8BeanSerializerModifier也扩展了BeanSerializerModifier,不过只是优化了一些细节。
标签: java json spring-boot jackson serialization