class 属性更改时 Jackson ObjectMapper readValue 的预期行为
Jackson ObjectMapper readValue expected behavior when class properties change
我需要更改 ObjectMapper serialized/deserialized class 的属性。
这是我的class。
// Old version
Class A {
String id;
String name;
}
// New version
Class A {
String id;
String firstName;
String secondName;
}
我序列化对象 ObjectMapper.writeValueAsString()
,将其发送到队列中稍后处理,收到后通过 ObjectMapper.readValue()
反序列化。
如果旧版本的 Class A 被序列化,但反序列化时 readValue()
的预期行为是什么 - Class A 已更新为新版本。
firstName
和 secondName
会为空吗?或者 readValue()
抛出异常?
这里的解决方案是什么才能顺利进行更改。
要回答第一部分,如果旧对象被反序列化,预期的行为是什么,objectMapper.readValue()
将反序列化为 firstName
和 secondName
为 null
而 name
是任何设置。 (我期待一个例外,但事实并非如此)。
关于如何进行转换:
我不会删除name
。我会将其与 firstName
和 secondName
.
一起保存
// Intermediate version
Class A {
String id;
String name;
String firstName;
String secondName;
}
name
将是一个虚拟持有者,序列化时不使用。
public void write(int id, String firstName, String secondName) {
A a = new A();
a.setId(id);
a.setFirstName(firstName);
a.setSecondName(secondName);
bufferedWriter.write(objectMapper.writeValueAsString(a));
}
根据空值检查我会知道对象是属于旧版本还是新版本。
public void read(String message) {
A a = objectMapper.readValue(message);
if(a.getName() != null) {
// This object is older version of class A
System.out.println("Name: " + a.getName());
metric.emit("OldObjectA", 1);
} else {
// This object is newer version of class A
System.out.println("Name: " + a.getFirstName() + " " + a.getSecondName())
}
}
一旦我确定我没有读取旧版本的对象,我将通过删除 name
.
来完成完全转换
// Newer version
Class A {
String id;
String firstName;
String secondName;
}
我需要更改 ObjectMapper serialized/deserialized class 的属性。
这是我的class。
// Old version
Class A {
String id;
String name;
}
// New version
Class A {
String id;
String firstName;
String secondName;
}
我序列化对象 ObjectMapper.writeValueAsString()
,将其发送到队列中稍后处理,收到后通过 ObjectMapper.readValue()
反序列化。
如果旧版本的 Class A 被序列化,但反序列化时 readValue()
的预期行为是什么 - Class A 已更新为新版本。
firstName
和 secondName
会为空吗?或者 readValue()
抛出异常?
这里的解决方案是什么才能顺利进行更改。
要回答第一部分,如果旧对象被反序列化,预期的行为是什么,objectMapper.readValue()
将反序列化为 firstName
和 secondName
为 null
而 name
是任何设置。 (我期待一个例外,但事实并非如此)。
关于如何进行转换:
我不会删除name
。我会将其与 firstName
和 secondName
.
// Intermediate version
Class A {
String id;
String name;
String firstName;
String secondName;
}
name
将是一个虚拟持有者,序列化时不使用。
public void write(int id, String firstName, String secondName) {
A a = new A();
a.setId(id);
a.setFirstName(firstName);
a.setSecondName(secondName);
bufferedWriter.write(objectMapper.writeValueAsString(a));
}
根据空值检查我会知道对象是属于旧版本还是新版本。
public void read(String message) {
A a = objectMapper.readValue(message);
if(a.getName() != null) {
// This object is older version of class A
System.out.println("Name: " + a.getName());
metric.emit("OldObjectA", 1);
} else {
// This object is newer version of class A
System.out.println("Name: " + a.getFirstName() + " " + a.getSecondName())
}
}
一旦我确定我没有读取旧版本的对象,我将通过删除 name
.
// Newer version
Class A {
String id;
String firstName;
String secondName;
}