Scala - разобрать json из более чем 22 элементов в класс case

Этот вопрос или подобные ранее были опубликованы, однако ни одно из решений больше не работает с последними библиотеками. После обширного поиска на данный момент я не нашел доказательств того, что последние версии наиболее популярных библиотек spray-json или play-json (или их плагины) могут обрабатывать этот случай. Есть ли что-то, что может анализировать json из более чем 22 элементов в класс класса scala? Поскольку scala 2.11 классы случаев больше не ограничены 22 элементами. Пожалуйста, только полностью работающие решения. Очевидный пример json ниже.

{
    "a": 1,
    "b": 2,
    "c": 3,
    "d": 4,
    "e": 5,
    "f": 6,
    "g": 7,
    "h": 8,
    "i": 9,
    "j": 10,
    "k": 11,
    "l": 12,
    "m": 13,
    "n": 14,
    "o": 15,
    "p": 16,
    "q": 17,
    "r": 18,
    "s": 19,
    "t": 20,
    "u": 21,
    "v": 22,
    "w": 23
}

UPDATE: Это случай, когда вы не имеете контроля над структурой json, например, он извлекается из стороннего api. Пример twitter tweet json: http://pastebin.com/h8fHAsd8

Ответ 1

circe, с автоматическим деривацией кодека, поддерживаемым Shapeless. Обратите внимание, что в отличие от декодирования класса case json4s, здесь не происходит отражения во время выполнения:

case class Foo(
  a: Int, b: Int, c: Int, d: Int, e: Int, f: Int, g: Int, h: Int, i: Int,
  j: Int, k: Int, l: Int, m: Int, n: Int, o: Int, p: Int, q: Int, r: Int,
  s: Int, t: Int, u: Int, v: Int, w: Int
)

import io.circe.generic.auto._, io.circe.jawn.decode

val json = """{
  "a": 1, "b": 2, "c": 3, "d": 4, "e": 5, "f": 6, "g": 7, "h": 8, "i": 9,
  "j": 10, "k": 11, "l": 12, "m": 13, "n": 14, "o": 15, "p": 16, "q": 17,
  "r": 18, "s": 19, "t": 20, "u": 21, "v": 22, "w": 23
}"""

val result: cats.data.Xor[io.circe.Error, Foo] = decode[Foo](json)

Здесь минимальный файл build.sbt:

scalaVersion := "2.11.7"

addCompilerPlugin(
  "org.scalamacros" % "paradise" % "2.1.0-M5" cross CrossVersion.full
)

libraryDependencies ++= Seq(
  "io.circe" %% "circe-core" % "0.1.1",
  "io.circe" %% "circe-generic" % "0.1.1",
  "io.circe" %% "circe-jawn" % "0.1.1"
)

Предстоящая версия 0.2.0 (в настоящее время доступная как моментальный снимок) включает в себя множество улучшений для генерического деривации, но для простого примера вроде этого поведение 0.1.1 одинаковое.

Ответ 2

Попробуйте использовать json4s:

scala> import org.json4s._
import org.json4s._

scala> import org.json4s.native.JsonMethods._
import org.json4s.native.JsonMethods._

scala> case class Foo(
     |                 a: String,
     |                 b: String,
     |                 c: String,
     |                 d: String,
     |                 e: String,
     |                 f: String,
     |                 g: String,
     |                 h: String,
     |                 i: String,
     |                 j: String,
     |                 k: String,
     |                 l: String,
     |                 m: String,
     |                 n: String,
     |                 o: String,
     |                 p: String,
     |                 q: String,
     |                 r: String,
     |                 s: String,
     |                 t: String,
     |                 u: String,
     |                 v: String,
     |                 w: String
     |                 )
defined class Foo

scala> 

scala>     implicit val formats = DefaultFormats
formats: org.json4s.DefaultFormats.type = [email protected]

scala>     val f = parse("{\n    \"a\": 1,\n    \"b\": 2,\n    \"c\": 3,\n    \"d\": 4,\n    \"e\": 5,\n    \"f\": 6,\n    \"g\": 7,\n    \"h\": 8,\n    \"i\": 9,\n    \"j\": 10,\n    \"k\": 11,\n    \"l\": 12,\n    \"m\": 13,\n    \"n\": 14,\n    \"o\": 15,\n    \"p\": 16,\n    \"q\": 17,\n    \"r\": 18,\n    \"s\": 19,\n    \"t\": 20,\n    \"u\": 21,\n    \"v\": 22,\n    \"w\": 23\n}")
           .extract[Foo]
f: Foo = Foo(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23)

Ответ 3

Для play-json расширения play-json предлагают расширение, поддерживающее > 22 поля и несколько других вариантов использования, таких как сериализация закрытых структур признаков, одноэлементных объектов и т.д.

import org.cvogt.play.json.Jsonx
implicit val jsonFormat = Jsonx.formatCaseClass[Foo] // Instead of Json.format

https://github.com/cvogt/play-json-extensions

circe/argonaut, безусловно, стоит проверить. Не уверены в том, как они сравниваются с точки зрения возможностей и стабильности по сравнению с расширениями play-json/play-json.

Ответ 4

Вдохновленный @cvogt и другими моими личными требованиями, я разработал библиотеку для прозрачного управления через макроs > 22 поля и другие функции.

Библиотека здесь и документация

Аннотации JsonFormat создают через макрос "сутенер" json-формат, который управляет множеством вещей.

Основные функции:

  • Воспроизведение JSON для ScalaJS
  • Аннотации макросов JsonFormat для ленивых людей
  • Значения полей по умолчанию, заполненные отсутствующим JSON
  • Переписать поле для воспроизведения JSON ( "ключ" )
  • +22 форматирование класса поля и многое другое. Воспроизведение Json Extension.
  • Jad Datetime для Scala и ScalaJS
  • Сильное типизированное перечисление (String и Int) для Scala и ScalaJS
  • Типы вариантов