0

我正在尝试通过 REST api 将 Javers 更改列表作为 JSON 发送。虽然 Jackson 可以通过加载相应的模块来处理 Java 8 Optionals,但它无法序列化 Change 对象。当我自己使用 Optionals 创建一个类时,序列化按预期工作。

要重现一个可以运行以下 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
    }
  }
]

自定义类按预期序列化:

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"
}

Javers Change 课程有什么特别之处,Jackson 拒绝序列化 Optionals?

4

2 回答 2

2

Jackson 不知道 Javers 的 Optionals 并试图将它们序列化为标准 Java Bean,在这种情况下这是错误的。您可以通过为 Jackson 编写自定义序列化程序来修复它。

Javers 的 Optionals 存在是因为用 Java8 Optionals 替换它们会阻碍 Java7 客户端。

于 2016-10-03T21:40:28.167 回答
0

刚刚又遇到了类似的问题,并在这里记住了我的问题。万一有人需要解决方案。这是 Javers Optional 的自定义 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();
    }
  }
}
于 2017-06-08T13:42:02.120 回答