当前位置: 首页 > 知识库问答 >
问题:

Jackson没有从Javers Change对象转换嵌套Java8可选,它有什么特别之处?

虞承泽
2023-03-14

我试图通过RESTAPI以JSON的形式发送Javers更改列表。虽然Jackson可以通过加载相应的模块来处理Java8选项,但它无法序列化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"
}

杰克森拒绝将期权系列化的贾维斯换人班有什么特别之处?

共有2个答案

金令秋
2023-03-14

我又遇到了类似的问题,还记得我的问题。以防有人需要解决方案。以下是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();
    }
  }
}
郑佐
2023-03-14

Jackson不知道Javers的选项,并试图将它们序列化为一个标准JavaBean,这在本例中是错误的。您可以通过为Jackson编写自定义序列化程序来修复它。

Javers的Optionals之所以存在,是因为用Java8 Optionals替换它们会阻止Java7客户端。

 类似资料:
  • 问题内容: 有人可以提供一个示例或参考,该示例或参考提供一种使用Jackson库将嵌套JAVA对象转换为JSON输出的方法的方法。我没有转换平面JAVA对象的问题。但是,JSON库显示嵌套的对象名称和类型,而不是其子对象。我几乎可以利用此处提供的相同代码http://www.mkyong.com/java/jackson-2-convert- java-object-to-from-json/ 。

  • 我有一个嵌套的JSON对象,如下所示: 我想将其转换为: 我如何使用JOLT实现这一点?感谢您的参与。

  • 下面有一个实体类,有两个字符串字段:name和description。description字段将包含一个原始JSON值,例如{“abc”:123} 如果存在@JSONRAWValue注释,建议如何将创建的JSON字符串编组回to Entity对象?我是不是遗漏了另一个注释? 谢谢

  • 问题内容: 我需要测试返回可选值的表达式是否为。这似乎很容易,但是这里是代码。 由于某种原因,这令我不悦。 对我来说看起来好多了,但是我实际上不需要该物品,我只需要知道是否退货即可。因此,我使用了以下内容。 我在这里想念些微妙的东西吗?我想和这里是等价的。 更新以解决答案中的一些问题 我不明白之间的差别和,虽然我一般使用。在这种情况下,在块之后推入将获得混合的块的布尔比较与if的布尔比较。 通配符

  • 问题内容: 我是JSON和JavaScript对象的新手。 有人可以解释JSON和JavaScript对象之间的区别吗? 它们有什么用? 这个比那个好吗?还是取决于情况? 什么时候使用哪个,在什么情况下? 为什么首先创建JSON?它的主要目的是什么? 有人可以举例说明何时应该使用JSON而不是JavaScript对象,反之亦然吗? 问题答案: 首先,您应该知道什么是JSON: 它是与 语言无关的

  • 问题内容: 后者是否仅引用由自定义构造函数创建的非原始函数对象(例如,var bird1 = new Bird();)? 问题答案: 这两个术语在ECMAScript规范中定义: 本机对象 ECMAScript实现中的对象,其语义由此规范而不是由主机环境完全定义。 注:本规范中定义了标准本机对象。一些本地对象是内置的。其他的可以在执行ECMAScript程序的过程中构造。 宿主对象 主机环境提供的