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 라이브러리를 작성하는 것은 할 일 목록 앱을 코딩하는 Scala 커뮤니티 버전입니다.

매우 다양한 대안이 있습니다. 특정 순서없이 메모와 함께 나열합니다.

  1. parsing.json.JSON이 - 경고 이 라이브러리 것은까지만 스칼라 버전 2.9.x 사용할 수 있습니다 (최신 버전에서 제거)
  2. spray-json- Spray 프로젝트에서 추출
  3. Jerkson ±- 멋진 라이브러리 (Java Jackson 위에 빌드 됨)를 경고 하지만 이제는 포기합니다. 이것을 사용하려면 Scalding 프로젝트의 예제를 따르고 backchat.io 포크를 사용하십시오.
  4. sjson - Debasish Ghosh 저
  5. lift-json- Lift 프로젝트와 별도로 사용 가능
  6. json4s 💣 § ±-다른 JSON 라이브러리에서 사용할 수있는 표준 JSON AST를 만들려고 시도하는 lift-json에서 추출한 것입니다. Jackson 지원 구현 포함
  7. Argonaut 💣 §-Scalaz 뒤에있는 사람들이 만든 Scala 용 FP 지향 JSON 라이브러리
  8. play-json ±-이제 독립형으로 사용할 수 있습니다. 자세한 내용이 답변을 참조하십시오.
  9. 디종 - A, 편리한 안전하고 효율적인 JSON 라이브러리 사용 jsoniter - 스칼라 후드.
  10. sonofjson- 매우 간단한 API를 목표로하는 JSON 라이브러리
  11. Jawn -Jackson 이상 속도를 목표로하는 Erik Osheim의 JSON 라이브러리
  12. Rapture JSON ±-2, 4, 5, 6, 7, 11 또는 Jackson을 백엔드로 사용할 수있는 JSON 프런트 엔드
  13. circe 💣- 스칼라 대신 고양이 위에 지어진 Argonaut 포크
  14. jsoniter-scala- 초고속 JSON 코덱의 컴파일 타임 생성을위한 Scala 매크로
  15. jackson-module-scala - Scala 관련 데이터 유형을 지원 하기위한 Jackson 용 추가 모듈
  16. borer -Scala의 효율적인 CBOR 및 JSON (역) 직렬화

💣 = 수정 된 보안 취약점 없음, § = Scalaz 통합 있음, ± = Jackson과의 상호 운용 지원 JsonNode

Snowplow 에서는 Jackson 백엔드와 함께 json4s를 사용합니다. 우리는 Argonaut에 대해서도 좋은 경험을했습니다.


8
lift-json이 더 큰 LIft 프로젝트에 번들로 포함되어 있다는 것은 사실이 아닙니다. 여러분은 단순히 lift-json에 의존 할 수 있으며 Lift-json의 다른 어떤 것도 여러분의 프로젝트에 오지 않을 것입니다.
fmpwizard 2013 년

3
@AlexDean : parsing.json.JSON에 대해 무엇이 그렇게 나쁜가요?
Matthias Braun

플레이 JSON처럼 보인다는 재생 2.2과 함께 출시되며, 이미 지금 사용할 수 있습니다 mandubian.com/2013/02/21/play-json-stand-alone
크리스티안

2
@BjornTipling-좋은 점, 2.11에서 더 이상 사용되지 않는다는 언급을 찾을 수 없습니다. 그 주석 제거
알렉스 딘

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
"net.liftweb"% "lift-json_2.10"% "2.5.1"에 대한 +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 2011

9
이 라이브러리는 작성자가 포기했습니다. 대안이 있습니까?
zjffdu

1
"I / O, 암호화 및 JSON 및 XML 처리 작업과 같은 일반적인 프로그래밍 작업을 위해 아름다운 관용적 Scala API를 제공하는 Scala 라이브러리 제품군"인 rapture.io를 잊지 마십시오 .
Piohen 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

조금 늦었을 수도 있지만 실제로 플레이 프레임 워크에서 json 라이브러리를 사용하는 것이 좋습니다. 문서를 볼 수 있습니다 . 현재 2.1.1 릴리스에서는 전체 플레이 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
참고 : Play의 JSON 라이브러리는 Typesafe 스냅 샷 저장소에서 이미 사용할 수 있습니다. repo.typesafe.com/typesafe/snapshots/com/typesafe/play/…
Tvaroh

... 이렇게 추가 할 수 있습니다 .
bluenote10 2014 년

공식적으로 sbt 튜토리얼
serv-inc

5

Genson 을 확인해야합니다 . 그것은 단지 작동하고 Scala의 기존 대안의 대부분보다 훨씬 사용하기 쉽습니다. 빠르고, 다른 라이브러리 (jodatime, json4s DOM api ...)와 많은 기능 및 통합이 있습니다.

암시 적, 기본 사례를위한 사용자 지정 판독기 / 작성기, 연산자 오버로드로 인한 ilisible 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 저자이지만 객관적이지 않습니다. :)


꽤 멋진 댐, 수치가 하나의 문제가 github.com/owlike/genson/issues/82
samthebest

5

다음은 .NET을 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 등으로 작업할지 결정합니다 (가져 오기에서도 가능).
  • 한 줄의 코드로 많은 작업을 수행합니다.

페이지에서 휴거 예제를 복사 / 붙여 넣기하고 싶지 않습니다. Rapture의 기능에 대한 멋진 프레젠테이션은 SBTB 2014에서 Jon Pretty에 의해 제공되었습니다. 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"

null 일 수도있는 값인 Option 에 대해 잘 알고 있는지 확인하십시오 (널 안전하다고 생각합니다). Argonaut는 Scalaz 를 사용 하므로 기호 \/(또는 연산) 처럼 이해하지 못하는 것이 있으면 아마도 Scalaz 일 것입니다.


2

이것을 시도해 볼 수 있습니다 : https://github.com/momodi/Json4Scala

간단하고 코드가 300 줄 미만인 스칼라 파일이 하나뿐입니다.

샘플이 있습니다.

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

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 라이브러리를 사용합니다. 여기서 전체 프레임 워크가 아닌 JSON 라이브러리에 대해서만 mavn repo를 찾을 수 있습니다.

    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

JSON 버전 의 SON 도 제공합니다 .

import nl.typeset.sonofjson._

arr(
  obj(id = 1, name = "John)
  obj(id = 2, name = "Dani)
)

나는 이것을 사용하고 싶지만 maven에 없기 때문에 내 종속성에 추가하는 방법을 알 수 없습니다.
Jason Wolosonovich

0

Play는 Play Framework, Play WS 에서 독립적으로 JSON을 처리하기위한 모듈을 출시했습니다.

그것에 대한 블로그 게시물을 작성했습니다. http://pedrorijo.com/blog/scala-json/ 에서 확인 하십시오.

케이스 클래스와 Play WS (이미 Play Framework에 포함되어 있음)를 사용하면 간단한 한 줄의 암시 적 코드로 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.