我需要将 scala 案例类的层次结构序列化为 JSON 以将它们存储在数据库中。我目前正在使用 json4s,它运行良好。但是,在 Java 中反序列化时,杰克逊需要我有一个空的构造函数来表示 case 类(不存在)。
我尝试的另一个选项是在我的scala库中定义一个反序列化函数,将其导入Java代码并在运行时运行它以读取字符串并构建层次结构的相对类。通过这种方式,我能够在Java世界中重建对象。之后,我想返回这个对象:如果我将其作为对象返回,我将无法正确序列化它(杰克逊使用与 json4s 不同的逻辑);如果我使用我的 scala 函数,我可以创建一个字符串并返回它,但由于某些原因它被转义返回:
"{"jsonClass":"TimeExtremaConfig","name":"payment_first_seen_hotel_id_on_agency"}
有没有更好的方法来解决这个问题?要么找到一种方法来反序列化案例类并到处使用 jackson,要么避免在第二个选项中进行转义
你试过使用Jackson Scala模块吗?
它在处理 Scala中的案例类实例方面做得很好:
case class Parent(name: String, children: List[Child])
case class Child(name: String)
def test(): Unit = {
val mapper = new ObjectMapper() with ScalaObjectMapper
mapper.registerModule(DefaultScalaModule)
val bobString = mapper.writeValueAsString(Parent("Bob", List(Child("Alice"))))
println(s"String: $bobString")
val bob = mapper.readValue[Parent](bobString)
println(s"Object: $bob")
}
输出:
String: {"name":"Bob","children":[{"name":"Alice"}]}
Object: Parent(Bob,List(Child(Alice)))
你可以从Java端有效地做同样的事情(请原谅集合互操作):
final ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new DefaultScalaModule());
final Child alice = new Child("Alice");
final List<Child> children = new ArrayList<>();
children.add(alice);
final String bobString = mapper.writeValueAsString(
new Parent("Bob",
JavaConversions.asScalaBuffer(children).toList()));
System.out.println(bobString);
final Parent bob = mapper.readValue(bobString, Parent.class);
System.out.println(bob);
听起来你可以控制Scala库,试试用case类的JsonCreator注释怎么样?我们必须在 Scala 案例类中使用@JsonProperty吗?
虽然它看起来不是很好,但它告诉杰克逊使用参数化构造函数而不是寻找默认构造函数。