Сериализация классов кейсов Scala и десериализация их в Java - PullRequest
1 голос
/ 18 апреля 2019

Мне нужно сериализовать иерархию классов дел Scala в виде JSON, чтобы сохранить их в БД. Я в настоящее время использую json4s, и он работает довольно хорошо. Однако при десериализации в Java Джексон требует, чтобы у меня был пустой конструктор для case-классов (который не существует).

Другой вариант, который я пробовал, - определить функцию десериализации в моей библиотеке scala, импортировать ее в код Java и запустить во время выполнения, чтобы прочитать строку и построить относительный класс иерархии. Таким образом, я могу реконструировать объект в мире Java. После этого я хочу вернуть этот объект: если я верну его как объект, я не смогу его правильно сериализовать (Джексон использует другую логику, чем json4s); если я использую свою функцию scala, я могу создать строку и вернуть ее, но по некоторым причинам она возвращается с экранированием:

"{\"jsonClass\":\"TimeExtremaConfig\",\"name\":\"payment_first_seen_hotel_id_on_agency\"}

Есть ли лучший способ решить эту проблему? Либо найти способ десериализации классов дел и повсеместно использовать Джексона, либо избежать выхода из второго варианта

Ответы [ 2 ]

0 голосов
/ 21 апреля 2019

похоже, у вас есть контроль над библиотекой scala, как насчет того, чтобы попробовать аннотацию JsonCreator с классом case? Должны ли мы использовать @JsonProperty в классах дел Scala?

Хотя это выглядит не очень хорошо, он говорит Джексону использовать параметризованный конструктор вместо поиска конструктора по умолчанию.

0 голосов
/ 18 апреля 2019

Вы пытались использовать Модуль Джексона Скала ?

Он довольно хорошо справляется с обработкой экземпляров классов дел в 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...