Разбор "stringified" JSON в scala / play - PullRequest
       6

Разбор "stringified" JSON в scala / play

2 голосов
/ 08 февраля 2020

Я реализую Scala / Play API (apiA), который использует API (apiB), который я не могу контролировать. ApiB возвращает ответ JSON, который в некоторых случаях содержит JSON, встроенный в строки. Пример:

{
  "name":"some_name",
  "scores": "[[10,15]]",
  "data": "{\"attr1\":\"value1\",\"attr2\":\"value3\"}"
}

ApiA должен получить доступ к значению name перед передачей всех данных клиенту, и он должен быть предоставлен клиенту как правильный JSON. Я рассматриваю разбор необработанного ответа в

case class Response(name: String, scores: JsValue, data: JsValue)

или

case class Response(name: String, scores: Seq[Seq[Int]], data: Map[String, String])

На данный момент не имеет значения, какие типы scores и data анализируются как Пока это не строка, содержащая JSON.

Теперь, если ответ JSON был правильно сформирован, формат записи / чтения / записи был бы простым, но я как бы ломаю голову над тем, как получить о преобразовании содержимого в JSON перед синтаксическим анализом в окончательные типы.

Буду признателен за любую помощь.

1 Ответ

4 голосов
/ 08 февраля 2020
case class Response(name: String, scores: Seq[Seq[Int]], data: Map[String, String])

import play.api.libs.json._

val stringified = Reads[JsValue] {
  _.validate[String].flatMap { raw =>
    try {
      JsSuccess(Json.parse(raw))
    } catch {
      case cause =>
        JsError(cause.getMessage)
    }
  }
}

implicit val respReads = Reads[Response] { js =>
  for {
    name <- (js \ "name").validate[String]
    scores <- (js \ "scores").validate(
      stringified).flatMap(_.validate[Seq[Seq[Int]]])
    data <- (js \ "data").validate(
      stringified).flatMap(_.validate[Map[String, String]])
  } yield Response(name, scores, data)
}

Json.parse("""{
  "name":"some_name",
  "scores": "[[10,15]]",
  "data": "{\"attr1\":\"value1\",\"attr2\":\"value3\"}"
}""").validate[Response]
// JsSuccess(Response(some_name,Vector(Vector(10, 15)),Map(attr1 -> value1, attr2 -> value3)),)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...