Scalaで使用するJSONライブラリは何ですか?[閉まっている]


125

次のようなJSON文字列を作成する必要があります。

[
  { 'id': 1, 'name': 'John'},
  { 'id': 2, 'name': 'Dani'}
]

val jArray = JsArray();
jArray += (("id", "1"), ("name", "John"))
jArray += (("id", "2"), ("name", "Dani"))
println(jArray.dump)

私はに行を追加できるようにする必要がありjArray、のようなものをjArray += ...

これに最も近いライブラリ/ソリューションは何ですか?


回答:


219

残念ながら、JSONライブラリを作成することは、ToDoリストアプリをコーディングするScalaコミュニティのバージョンです。

かなりさまざまな選択肢があります。私はそれらを特定の順序でリストし、メモを付けています:

  1. parsing.json.JSON - 警告このライブラリにのみアップ(新しいバージョンで削除)Scalaのバージョン2.9.xに提供されています
  2. スプレーjson-スプレープロジェクトから抽出
  3. Jerkson ±- (Java Jacksonの上に構築された)素晴らしいライブラリに警告しますが、現在は放棄されています。これを使用する場合は、Scaldingプロジェクトの例に従って、backchat.ioフォークを使用してください。
  4. sjson -Debasish Ghoshによる
  5. lift-json -Liftプロジェクトとは別に使用できます
  6. json4s 💣 、§± -他のJSONライブラリを使用することができ、標準のJSON ASTを作成しようとしているリフトJSONから抽出。ジャクソン支援の実装が含まれています
  7. アルゴノート 💣 Scalazの背後にある人々からScalaのためのA FP指向のJSONライブラリ、 - §
  8. play-json ±-スタンドアロンで利用可能になりました。詳細この回答を参照してください
  9. ディジョン -便利、安全かつ効率的なJSONライブラリ、用途jsoniter-Scalaのフードの下。
  10. sonofjson-超シンプルなAPIを目指したJSONライブラリ
  11. Jawn -ジャクソン・オア・高速化を目指しエリックOsheimによるJSONライブラリー
  12. Rapture JSON ± -2、4、5、6、7、11またはJacksonをバックエンドとして使用できるJSONフロントエンド
  13. キルケ 💣 -アルゴノートのフォークは、上に構築されたの代わりにscalazの
  14. jsoniter-scala-超高速JSONコーデックをコンパイル時に生成するためのScalaマクロ
  15. jackson-module-scala - Scala固有のデータ型をサポートするためのJacksonのアドオンモジュール
  16. borer -Scalaでの効率的なCBORおよびJSON(デ)シリアライゼーション

💣=セキュリティの脆弱性は修正されていません、§= Scalaz統合があります、±=ジャクソンとの相互運用をサポートしています JsonNode

除雪我々は、ジャクソンのバックエンドでjson4sを使用します。Argonautでも良い経験をしました。


8
lift-jsonがより大きなLIftプロジェクトにバンドルされているとは限りません。単にlift-jsonに依存するだけで、Liftプロジェクトからのプロジェクトは何もプロジェクトに送られません。
fmpwizard 2013年

3
@AlexDean:parsing.json.JSONの何が悪いのですか?
Matthias Braun 2013年

play-jsonはPlay 2.2でリリースされる予定で、すでに使用できます:mandubian.com/2013/02/21/play-json-stand-alone
Christiaan

2
@BjornTipling-良い点、2.11で非推奨になったという記述は今のところ見つかりません。コメントを削除
Alex Dean

2
リストでは、jackson-module-scalaを一番上に配置する必要があります。これは、パフォーマンス、シンプルさ、メンテナンス、およびサポートで群を抜いて優れています。
lyomi

17

Lift-jsonはバージョン2.6であり、非常に適切に動作します(また、非常によくサポートされています。メンテナーは、ユーザーが見つけたバグをいつでも修正する準備ができています。githubリポジトリでそれを使用した例を見つけることができます。

メンテナー(Joni Freeman)は、Liftメーリングリストでいつでも連絡できます。メーリングリストには他にも非常に役立つユーザーがいます。

@Alexeyが指摘するように、他のScalaバージョンでライブラリを使用したい場合は、次のように2.11.x変更scalaVersionして使用%%します。

scalaVersion := "2.11.5" 

"net.liftweb" %% "lift-json" % "2.6"

liftweb.netサイトをチェックして、時間の経過とともに最新バージョンを確認できます。


3
私はlift-jsonも使用しており、それが素晴らしいライブラリであることを保証できます。JSONの解析と生成/シリアライズの両方が非常に簡単になります。
Dan Simon、

1
+1 "net.liftweb"% "lift-json_2.10"% "2.5.1"
Dylan Hogg

2
Scala 2.11の場合: "net.liftweb"% "lift-json_2.11"% "2.6-M4"
Alexey

15

jerksonの使用をお勧めします。これは、最も基本的な型変換をサポートしています。

scala> import com.codahale.jerkson.Json._

scala> val l = List( 
                 Map( "id" -> 1, "name" -> "John" ),
                 Map( "id" -> 2, "name" -> "Dani")
               )

scala> generate( l )

res1: String = [{"id":1,"name":"John"},{"id":2,"name":"Dani"}]

2
また、いくつかの非常にエレガントタイプセーフなJSON処理を可能にするケースクラスに対するいくつかの本当に素晴らしいサポートがあります。
Thomas Lockney

9
このライブラリは作成者によって中止されましたが、代替手段はありますか?
zjffdu

1
rapture.ioを忘れないでください。これは、「I / O、暗号化、JSON&XML処理などの一般的なプログラミングタスクに美しい慣用的なScala APIを提供するScalaライブラリのファミリーです。」
ピオヘン2014年

12

リストの7番目は、ジャークソンを使用していないジャクソンです。Scalaオブジェクト(ケースクラスなど)をサポートしています。

以下は、それを使用する方法の例です。

object MyJacksonMapper extends JacksonMapper
val jsonString = MyJacksonMapper.serializeJson(myObject)
val myNewObject = MyJacksonMapper.deserializeJson[MyCaseClass](jsonString)

これにより、非常に簡単になります。さらに、XmlSerializerもあり、JAXBアノテーションのサポートは非​​常に便利です。

このブログ投稿では、JAXBアノテーションとPlayフレームワークでの使用について説明しています。

http://krasserm.blogspot.co.uk/2012/02/using-jaxb-for-xml-and-json-apis-in.html

これが私の現在のJacksonMapperです。

trait JacksonMapper {

  def jsonSerializer = {
    val m = new ObjectMapper()
    m.registerModule(DefaultScalaModule)
    m
  }

  def xmlSerializer = {
    val m = new XmlMapper()
    m.registerModule(DefaultScalaModule)
    m
  }

  def deserializeJson[T: Manifest](value: String): T = jsonSerializer.readValue(value, typeReference[T])
  def serializeJson(value: Any) = jsonSerializer.writerWithDefaultPrettyPrinter().writeValueAsString(value)
  def deserializeXml[T: Manifest](value: String): T = xmlSerializer.readValue(value, typeReference[T])
  def serializeXml(value: Any) = xmlSerializer.writeValueAsString(value)

  private[this] def typeReference[T: Manifest] = new TypeReference[T] {
    override def getType = typeFromManifest(manifest[T])
  }

  private[this] def typeFromManifest(m: Manifest[_]): Type = {
     if (m.typeArguments.isEmpty) { m.erasure }
     else new ParameterizedType {
       def getRawType = m.erasure

       def getActualTypeArguments = m.typeArguments.map(typeFromManifest).toArray

       def getOwnerType = null
     }
  }
}   

8

多分私は少し遅れましたが、あなたは本当にplayフレームワークからjsonライブラリを使用しようとするべきです。ドキュメンテーションを見ることができます。現在の2.1.1リリースでは、play 2全体なしでは個別に使用できなかったため、依存関係は次のようになります。

val typesaferepo  = "TypeSafe Repo" at "http://repo.typesafe.com/typesafe/releases"
val play2 = "play" %% "play" % "2.1.1"

それはあなたにボード上のすべてのものを備えた全体のプレイフレームワークをもたらします。

しかし、私が知っているように、Typesafeの人たちはそれを2.2リリースで分離する計画を持っています。したがって、2.2-snapshotのスタンドアロンのplay-jsonがあります。


2
FYI:プレイのJSONライブラリは、タイプセーフスナップショットレポですでに提供されています:repo.typesafe.com/typesafe/snapshots/com/typesafe/play/...
Tvaroh

...のように追加できます。
bluenote10 2014年


5

Gensonを確認してください。それは機能するだけで、Scalaの既存のほとんどの代替手段よりもはるかに使いやすくなっています。それは高速で、多くの機能と他のいくつかのライブラリ(jodatime、json4s DOM api ...)との統合があります。

インプリシット、基本的なケース用のカスタムリーダー/ライター、オペレーターの過負荷による不適格なAPIなどの空想の不要なコードなしで...

使い方は次のように簡単です:

import com.owlike.genson.defaultGenson_

val json = toJson(Person(Some("foo"), 99))
val person = fromJson[Person]("""{"name": "foo", "age": 99}""")

case class Person(name: Option[String], age: Int)

免責事項:私はGensonsの作者ですが、それは私が客観的ではないという意味ではありません:)


かっこいい、かっこいい1つの問題github.com/owlike/genson/issues/82
samthebest

5

次に、jsonを使用しjson4sたファイルの書き込みと読み取りの基本的な実装を示します。

import org.json4s._
import org.json4s.jackson.JsonMethods._
import org.json4s.JsonDSL._
import java.io._
import scala.io.Source


object MyObject { def main(args: Array[String]) {

  val myMap = Map("a" -> List(3,4), "b" -> List(7,8))

  // writing a file 
  val jsonString = pretty(render(myMap))

  val pw = new PrintWriter(new File("my_json.json"))
  pw.write(jsonString)
  pw.close()

  // reading a file 
  val myString = Source.fromFile("my_json.json").mkString
  println(myString)

  val myJSON = parse(myString)

  println(myJSON)

  // Converting from JOjbect to plain object
  implicit val formats = DefaultFormats
  val myOldMap = myJSON.extract[Map[String, List[Int]]]

  println(myOldMap)
 }
}

4

Jawnは、Scalaの非常に柔軟なJSONパーサーライブラリです。また、カスタムASTの生成も可能です。ASTにマッピングするには、小さな特性を指定するだけです。

少しのJSON解析を必要とする最近のプロジェクトでうまく機能しました。


4

回答のリストに携挙が欠けているようです。これはhttp://rapture.io/から取得でき、(特に)次のことができます。

  • JSONバックエンドを選択します。これは、(インポートで)すでに使用している場合に非常に便利です。
  • Try、Future、Option、Eitherなどを使用するかどうかを決定します(インポートでも)
  • 1行のコードで多くの作業を行います。

Raptureのサンプルをそのページからコピー/貼り付けしたくありません。Raptureの機能に関する素晴らしいプレゼンテーションがJBTによってSBTB 2014で行われました:https : //www.youtube.com/watch?v= ka5-OLJgybI


3

@AlaxDeanの7番目の回答であるArgonautは、sbtとintellijを使ってすばやく作業できる唯一の人です。実際、json4sも少し時間がかかりましたが、生のASTを処理することは私が望んでいたものではありません。私はbuild.stに単一行を入力することにより、argonautを動作させました。

libraryDependencies += "io.argonaut" %% "argonaut" % "6.0.1"

そして、JSONを取得できるかどうかを確認する簡単なテスト:

package mytest


import scalaz._, Scalaz._
import argonaut._, Argonaut._

object Mytest extends App {

  val requestJson  =
    """
    {
      "userid": "1"
    }
    """.stripMargin

  val updatedJson: Option[Json] = for {
    parsed <- requestJson.parseOption
  } yield ("name", jString("testuser")) ->: parsed

  val obj = updatedJson.get.obj
  printf("Updated user: %s\n", updatedJson.toString())
  printf("obj : %s\n", obj.toString())
  printf("userid: %s\n", obj.get.toMap("userid"))
}

その後

$ sbt
> run
Updated user: Some({"userid":"1","name":"testuser"})
obj : Some(object[("userid","1"),("name","testuser")])
userid: "1"

Optionについて十分に理解していることを確認してください。これは、nullの可能性もある単なる値です(null安全だと思います)。ArgonautはScalazを使用しているので、シンボル\/(または操作)のように理解できないものを見つけた場合、それはおそらくScalazです。


2

これを試すことができますhttps : //github.com/momodi/Json4Scala

シンプルで、コードが300行未満のscalaファイルが1つだけあります。

サンプルがあります:

test("base") {
    assert(Json.parse("123").asInt == 123)
    assert(Json.parse("-123").asInt == -123)
    assert(Json.parse("111111111111111").asLong == 111111111111111l)
    assert(Json.parse("true").asBoolean == true)
    assert(Json.parse("false").asBoolean == false)
    assert(Json.parse("123.123").asDouble == 123.123)
    assert(Json.parse("\"aaa\"").asString == "aaa")
    assert(Json.parse("\"aaa\"").write() == "\"aaa\"")

    val json = Json.Value(Map("a" -> Array(1,2,3), "b" -> Array(4, 5, 6)))
    assert(json("a")(0).asInt == 1)
    assert(json("b")(1).asInt == 5)
}
test("parse base") {
    val str =
        """
          {"int":-123, "long": 111111111111111, "string":"asdf", "bool_true": true, "foo":"foo", "bool_false": false}
        """
    val json = Json.parse(str)
    assert(json.asMap("int").asInt == -123)
    assert(json.asMap("long").asLong == 111111111111111l)
    assert(json.asMap("string").asString == "asdf")
    assert(json.asMap("bool_true").asBoolean == true)
    assert(json.asMap("bool_false").asBoolean == false)
    println(json.write())
    assert(json.write().length > 0)
}
test("parse obj") {
    val str =
        """
           {"asdf":[1,2,4,{"bbb":"ttt"},432]}
        """
    val json = Json.parse(str)
    assert(json.asMap("asdf").asArray(0).asInt == 1)
    assert(json.asMap("asdf").asArray(3).asMap("bbb").asString == "ttt")
}
test("parse array") {
    val str =
        """
           [1,2,3,4,{"a":[1,2,3]}]
        """
    val json = Json.parse(str)
    assert(json.asArray(0).asInt == 1)
    assert(json(4)("a")(2).asInt == 3)
    assert(json(4)("a")(2).isInt)
    assert(json(4)("a").isArray)
    assert(json(4)("a").isMap == false)
}
test("real") {
    val str = "{\"styles\":[214776380871671808,214783111085424640,214851869216866304,214829406537908224],\"group\":100,\"name\":\"AO4614【金宏达电子】现货库存 质量保证 欢迎购买@\",\"shopgrade\":8,\"price\":0.59,\"shop_id\":60095469,\"C3\":50018869,\"C2\":50024099,\"C1\":50008090,\"imguri\":\"http://img.geilicdn.com/taobao10000177139_425x360.jpg\",\"cag\":50006523,\"soldout\":0,\"C4\":50006523}"
    val json = Json.parse(str)
    println(json.write())
    assert(json.asMap.size > 0)
}

私はこれが好きです-小さなユースケースに最適-ライブラリは必要ありません。
Samik R 2016

2

ネストされたケースクラスを自動的に処理するという大きな利点を持つuPickleを使用します。

object SerializingApp extends App {

  case class Person(name: String, address: Address)

  case class Address(street: String, town: String, zipCode: String)

  import upickle.default._

  val john = Person("John Doe", Address("Elm Street 1", "Springfield", "ABC123"))

  val johnAsJson = write(john)
  // Prints {"name":"John Doe","address":{"street":"Elm Street 1","town":"Springfield","zipCode":"ABC123"}}
  Console.println(johnAsJson)

  // Parse the JSON back into a Scala object
  Console.println(read[Person](johnAsJson))  
}

これをに追加して、build.sbtuPickleを使用します。

libraryDependencies += "com.lihaoyi" %% "upickle" % "0.4.3"

0

私はPLAY JSONライブラリを使用しています

    val json = "com.typesafe.play" %% "play-json" % version
    val typesafe = "typesafe.com" at "http://repo.typesafe.com/typesafe/releases/"

それらを使用する方法についての非常に良いチュートリアルがここにあります:

http://mandubian.com/2012/09/08/unveiling-play-2-dot-1-json-api-part1-jspath-reads-combinators/

http://mandubian.com/2012/10/01/unveiling-play-2-dot-1-json-api-part2-writes-format-combinators/

http://mandubian.com/2012/10/29/unveiling-play-2-dot-1-json-api-part3-json-transformers/


JSON Playについてはすでに説明しました。
bluenote10 2014年


0

Playは、Play Framework、Play WSとは独立してJSONを処理するためのモジュールをリリースしました

それに関するブログ投稿を作成しました。http://pedrorijo.com/blog/scala-json/でチェックしてください。

ケースクラスとPlay WS(すでにPlay Frameworkに含まれています)を使用して、単純な1ライナーの暗黙的な方法でjsonクラスとケースクラスの間でケース変換します。

case class User(username: String, friends: Int, enemies: Int, isAlive: Boolean)

object User {
  implicit val userJsonFormat = Json.format[User]
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.