我目前正在致力于将一个遗留应用程序从java.util.Date类移植到java.time应用程序接口。我使用默认类型来保存类型信息。因为java.time类被标记为final,所以Jackson没有在JSON输出中添加任何类型信息。这在大多数情况下都是可以的,但在这种情况下除外:
我有一个类,它有一个Object类型的成员,它可以包含各种数据类型。它是在运行时填充的,所以我不知道它会提前包含哪种数据类型。然后将其序列化并发送到客户端,客户端对其进行反序列化并使用instanceof检查数据类型。这在java.util.Date中工作得很好,因为类型是序列化的。由于没有类型信息,ZonedDateTime被反序列化为一个字符串,这会在后面的代码中导致错误。
我已经阅读了关于不同DefaultTyping-Settings的杰克逊文档,但添加了最多类型信息的选项似乎是NON_FINAL,这仍然会导致这个问题。
我还试图编写自己的序列化程序并覆盖serializeWithType-Method,但它从未被调用过。
我可以编写一个包含ZonedDateTime的非最终包装类,但如果可能的话,我想避免这种情况。
这是我的ObjectMapper配置:
ObjectMapper myMapper = new ObjectMapper()
.enable(MapperFeature.AUTO_DETECT_CREATORS)
.enable(MapperFeature.AUTO_DETECT_FIELDS)
.enable(SerializationFeature.WRITE_DATES_WITH_ZONE_ID)
.disable(MapperFeature.AUTO_DETECT_GETTERS)
.disable(MapperFeature.AUTO_DETECT_SETTERS)
.disable(MapperFeature.USE_ANNOTATIONS)
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL)
.setSerializationInclusion(JsonInclude.Include.NON_NULL)
.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE)
.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY)
.registerModule(new JavaTimeModule());这是我现在得到的结果:
"2019-08-02T16:03:41.988+02:00[Europe/Berlin]"这就是我想要的:
["java.time.ZonedDateTime", "2019-08-02T16:03:41.988+02:00[Europe/Berlin]"]发布于 2019-08-08 18:00:20
由于另一个答案在我的情况下不适用,我已经实现了一个变通方法。它不是很优雅,如果有人有更好的解决方案,我会删除它,但目前它是有效的。
我是通过使用泛型实现以下包装类来实现的:
public class FinalClassContainer <T> {
private T containedObject;
public FinalClassContainer(T obj)
{
this.containedObject = obj;
}
public T getContainedClass()
{
return containedObject;
}
}这将产生以下输出:
[
"com.test.FinalClassContainer",
{
"containedObject": [
"java.time.ZonedDateTime",
"2019-08-08T11:22:00.996+02:00[Europe/Berlin]"
]
}
]这允许我在客户端调用container.getContainedClass(),它返回具有正确类型的对象。
发布于 2019-08-06 16:14:12
这可以通过为Jackson提供一个生成所需输出的getter方法来实现。如果你有一个实例变量的getter方法,你可以告诉Jackson忽略它:
public class MyBean
{
private Object obj;
// tell jackson to ignore standard getter method
@JsonIgnore
public Object getObj() {
return obj;
}
// this is the method that jackson will call during serialization
@JsonProperty("obj")
public String[] getObjForJson() {
return new String[] {
obj.getClass().getName(),
obj.toString()
};
}
}测试方法
public static void main(String[] args) {
MyBean myBean = new MyBean();
myBean.obj = ZonedDateTime.now();
ObjectMapper mapper = new ObjectMapper();
try {
mapper.writeValue(System.out, myBean);
} catch (Exception e) {
e.printStackTrace();
}
}输出:
{"obj":["java.time.ZonedDateTime","2019-08-06T11:09:30.467+03:00[Asia/Jerusalem]"]}https://stackoverflow.com/questions/57328109
复制相似问题