Jackson 不转换嵌套 Java 8 Optional from Javers Change 对象,有什么特别之处?
Jackson does not convert nested Java 8 Optional from Javers Change object, what is special about it?
我正在尝试通过 REST api 以 JSON 的形式发送 Javers 变更列表。虽然 Jackson 可以通过加载相应的模块来处理 Java 8 个 Optionals,但它无法序列化 Change 对象。当我自己用 Optionals 创建一个 class 时,序列化按预期工作。
要重现可以运行以下groovy脚本:
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module
import org.javers.core.JaversBuilder
import org.javers.repository.jql.QueryBuilder
@Grapes([
@Grab("com.fasterxml.jackson.core:jackson-core:2.8.3"),
@Grab(group='com.fasterxml.jackson.datatype', module='jackson-datatype-jdk8', version='2.8.3'),
@Grab('org.javers:javers-core:2.3.0')]
)
class Test {
def bar
def baz
Test(){
baz = "baz"
bar = "bar"
}
}
def test = new Test()
def javers = JaversBuilder.javers().build()
javers.commit("user", test)
test.bar = "foo"
javers.commit("user", test)
def objectMapper = new ObjectMapper()
objectMapper.registerModule(new Jdk8Module())
println objectMapper.writeValueAsString(javers.findChanges(QueryBuilder.anyDomainObject().build()))
这输出:
[
{
"commitMetadata": {
"empty": false,
"present": true
},
"propertyName": "bar",
"left": "bar",
"right": "foo",
"affectedGlobalId": {
"typeName": "Test"
},
"affectedLocalId": null,
"affectedObject": {
"empty": true,
"present": false
}
}
]
自定义 class 按预期序列化:
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module
@Grapes([
@Grab("com.fasterxml.jackson.core:jackson-core:2.8.3"),
@Grab(group='com.fasterxml.jackson.datatype', module='jackson-datatype-jdk8', version='2.8.3')]
)
class Test2 {
def bar
def baz
Test2(){
baz = Optional.of("baz")
bar = "bar"
}
}
def test = new Test2()
def objectMapper = new ObjectMapper()
objectMapper.registerModule(new Jdk8Module())
println objectMapper.writeValueAsString(test)
输出:
{
"bar": "bar",
"baz": "baz"
}
Jackson 拒绝序列化 Optionals 的 Javers Change class 有什么特别之处?
Jackson 不知道 Javers 的 Optionals 并试图将它们序列化为标准 Java Bean,但在这种情况下这是错误的。
您可以通过为 Jackson 编写自定义序列化程序来修复它。
Javers 的 Optionals 存在是因为用 Java8 Optionals 替换它们会
制动 Java7 个客户。
刚刚又遇到了类似的问题,记得我的问题在这里。如果有人需要解决方案。这是 Javers 可选的自定义 Jackson 序列化程序:
import java.io.IOException;
import org.javers.common.collections.Optional;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
@SuppressWarnings("rawtypes")
public class JaversOptionalSerializer extends StdSerializer<Optional> {
private static final long serialVersionUID = 8330773428393250826L;
public JaversOptionalSerializer() {
super(Optional.class);
}
@Override
public void serialize(final Optional value, final JsonGenerator gen, final SerializerProvider provider) throws IOException {
if(value.isPresent()){
JsonSerializer<Object> serializer = provider.findValueSerializer(value.get().getClass());
serializer.serialize(value.get(), gen, provider);
} else {
gen.writeNull();
}
}
}
我正在尝试通过 REST api 以 JSON 的形式发送 Javers 变更列表。虽然 Jackson 可以通过加载相应的模块来处理 Java 8 个 Optionals,但它无法序列化 Change 对象。当我自己用 Optionals 创建一个 class 时,序列化按预期工作。
要重现可以运行以下groovy脚本:
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module
import org.javers.core.JaversBuilder
import org.javers.repository.jql.QueryBuilder
@Grapes([
@Grab("com.fasterxml.jackson.core:jackson-core:2.8.3"),
@Grab(group='com.fasterxml.jackson.datatype', module='jackson-datatype-jdk8', version='2.8.3'),
@Grab('org.javers:javers-core:2.3.0')]
)
class Test {
def bar
def baz
Test(){
baz = "baz"
bar = "bar"
}
}
def test = new Test()
def javers = JaversBuilder.javers().build()
javers.commit("user", test)
test.bar = "foo"
javers.commit("user", test)
def objectMapper = new ObjectMapper()
objectMapper.registerModule(new Jdk8Module())
println objectMapper.writeValueAsString(javers.findChanges(QueryBuilder.anyDomainObject().build()))
这输出:
[
{
"commitMetadata": {
"empty": false,
"present": true
},
"propertyName": "bar",
"left": "bar",
"right": "foo",
"affectedGlobalId": {
"typeName": "Test"
},
"affectedLocalId": null,
"affectedObject": {
"empty": true,
"present": false
}
}
]
自定义 class 按预期序列化:
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module
@Grapes([
@Grab("com.fasterxml.jackson.core:jackson-core:2.8.3"),
@Grab(group='com.fasterxml.jackson.datatype', module='jackson-datatype-jdk8', version='2.8.3')]
)
class Test2 {
def bar
def baz
Test2(){
baz = Optional.of("baz")
bar = "bar"
}
}
def test = new Test2()
def objectMapper = new ObjectMapper()
objectMapper.registerModule(new Jdk8Module())
println objectMapper.writeValueAsString(test)
输出:
{
"bar": "bar",
"baz": "baz"
}
Jackson 拒绝序列化 Optionals 的 Javers Change class 有什么特别之处?
Jackson 不知道 Javers 的 Optionals 并试图将它们序列化为标准 Java Bean,但在这种情况下这是错误的。 您可以通过为 Jackson 编写自定义序列化程序来修复它。
Javers 的 Optionals 存在是因为用 Java8 Optionals 替换它们会 制动 Java7 个客户。
刚刚又遇到了类似的问题,记得我的问题在这里。如果有人需要解决方案。这是 Javers 可选的自定义 Jackson 序列化程序:
import java.io.IOException;
import org.javers.common.collections.Optional;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
@SuppressWarnings("rawtypes")
public class JaversOptionalSerializer extends StdSerializer<Optional> {
private static final long serialVersionUID = 8330773428393250826L;
public JaversOptionalSerializer() {
super(Optional.class);
}
@Override
public void serialize(final Optional value, final JsonGenerator gen, final SerializerProvider provider) throws IOException {
if(value.isPresent()){
JsonSerializer<Object> serializer = provider.findValueSerializer(value.get().getClass());
serializer.serialize(value.get(), gen, provider);
} else {
gen.writeNull();
}
}
}