Soru Scala 2.10 + Json serileştirme ve serileştirme


Scala 2.10, Jerkson ve lift-json gibi eski kütüphanelerin bazılarını (en azından şimdilik) kırmış görünüyor.

Hedef kullanılabilirlik aşağıdaki gibidir:

case class Person(name: String, height: String, attributes: Map[String, String], friends: List[String])

//to serialize
val person = Person("Name", ....)
val json = serialize(person)

//to deserialize
val sameperson = deserialize[Person](json)

Ancak, Scala 2.10 ile çalışan Json'u oluşturma ve serpiştirmenin mevcut yollarını bulmakta zorlanıyorum.

Bunu Scala 2.10'da yapmanın en iyi yöntemleri var mı?


36
2017-09-25 21:40


Menşei




Cevaplar:


Jackson hızlı JSON işlemek için bir Java kütüphanesidir. Jerkson projesi Jackson'ı sarar, ancak terkedilmiş gibi görünüyor. Jackson'a geçtim Scala Modülü yerel Scala veri yapılarına serileştirme ve serileştirme için.

Bunu almak için aşağıdakileri build.sbt:

libraryDependencies ++= Seq(
  "com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.1.3",
   ...
)

Daha sonra örnekleriniz, aşağıdaki Jackson sarıcısıyla birlikte çalışacaktır (jackson-modül-scala test dosyalarından çıkardım):

import java.lang.reflect.{Type, ParameterizedType}
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.`type`.TypeReference;

object JacksonWrapper {
  val mapper = new ObjectMapper()
  mapper.registerModule(DefaultScalaModule)

  def serialize(value: Any): String = {
    import java.io.StringWriter
    val writer = new StringWriter()
    mapper.writeValue(writer, value)
    writer.toString
  }

  def deserialize[T: Manifest](value: String) : T =
    mapper.readValue(value, typeReference[T])

  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
    }
  }
}

Diğer Scala 2.10 JSON seçenekleri arasında Twitter Scala-json Programlama Scala kitabına dayanarak - performans maliyetinde basittir. Ayrıca birde şu var sprey json, hangi kullanır yarım kaynatılmış ayrıştırma için. En sonunda, Oyunun JSON kullanımı güzel görünüyor, ancak Play projesinden kolayca ayrışmıyor.


38
2018-01-05 00:04



Jackson scala modülü Numaralandırma için iyi değil: stackoverflow.com/questions/15887785/... - Sebastien Lorber
Bu gece yapımında düzeltilebilir: github.com/FasterXML/jackson-module-scala/wiki/Enumerations - Kipton Barros
erasure kullanımdan kaldırılmış görünüyor - Mermoz
Kullanımdan kaldırılmış m.erasure iki yerde m.runtimeClass olarak değiştirilebilir ve harika çalışıyor - simbo1905


değinen json4s jackson, lift-json veya kendi yerel uygulamalarını uzun vadeli bir çözüm olarak sarar:


7
2018-03-05 02:12





Yürekten tavsiye ederim argonot scala'da json desteği için. Müşteri nesnesini serileştirmek için yapılandırmanız gereken tek şey bir satırdır:

implicit lazy val CodecCustomer: CodecJson[Customer] =
casecodec6(Customer.apply, Customer.unapply)("id","name","address","city","state","user_id")

Bu, sınıfınızı ona vermek için pezevenk edecek .asJson Bir dizeye dönüştüren yöntem. Ayrıca bir yöntem vermek için dize sınıfını pezevenk edecek .decodeOption[List[Customer]] dizeleri ayrıştırmak için. Sınıfınızdaki seçenekleri ele alır. İşte geçen bir test ve çalışan bir ana yöntemle çalışan bir çalışma sınıfıdır, tüm çalışanların iyi çalıştığını görmek için bir argonaut git klonuna girebilirsiniz:

package argonaut.example

import org.specs2.{ScalaCheck, Specification}
import argonaut.CodecJson
import argonaut.Argonaut._

case class Customer(id: Int, name: String, address: Option[String],
                    city: Option[String], state: Option[String], user_id: Int)

class CustomerExample extends Specification with ScalaCheck {

  import CustomerExample.CodecCustomer
  import CustomerExample.customers

  def is = "Stackoverflow question 12591457 example" ^
    "round trip customers to and from json strings " ! {
      customers.asJson.as[List[Customer]].toOption must beSome(customers)
    }
}

object CustomerExample {

  implicit lazy val CodecCustomer: CodecJson[Customer] =
    casecodec6(Customer.apply, Customer.unapply)("id","name","address","city","state","user_id")

  val customers = List(
    Customer(1,"one",Some("one street"),Some("one city"),Some("one state"),1)
    , Customer(2,"two",None,Some("two city"),Some("two state"),2)
    , Customer(3,"three",Some("three address"),None,Some("three state"),3)
    , Customer(4,"four",Some("four address"),Some("four city"),None,4)
  )

  def main(args: Array[String]): Unit = {

    println(s"Customers converted into json string:\n ${customers.asJson}")

    val jsonString =
      """[
        |   {"city":"one city","name":"one","state":"one state","user_id":1,"id":1,"address":"one street"}
        |   ,{"city":"two city","name":"two","state":"two state","user_id":2,"id":2}
        |   ,{"name":"three","state":"three state","user_id":3,"id":3,"address":"three address"}
        |   ,{"city":"four city","name":"four","user_id":4,"id":4,"address":"four address"}
        |]""".stripMargin


    var parsed: Option[List[Customer]] = jsonString.decodeOption[List[Customer]]

    println(s"Json string turned back into customers:\n ${parsed.get}")

  }
}

Geliştiriciler, katılımcılar için yardımcı ve duyarlı.


6
2017-09-07 20:39





Şimdi Scala 2.10'u destekleyen Jerkson'un bir çatalı var. https://github.com/randhindi/jerkson.


4
2018-03-17 08:46



IntelliJ Idea 12'de nasıl kurabilirim ve kullanabilirim? - Alan Coromano
Korkarım ki sana yardım edemem. Jerkson yerine sprey-json'a gittim. - Sebastian Ganslandt
önemli değil, nasıl kurdunuz? - Alan Coromano
Ben jerkson'u hiç yüklemedim, sadece orada daha yeni bir veryon olduğunu kaydetti :). Spray-json'a atıfta bulunursanız, bunu bir sbt bağımlılığı olarak işaret ettim. - Sebastian Ganslandt
Yükleyerek ne demek istiyorsun? Bir çeşit bağımlılık yönetimi oluşturma aracı kullanıyorsanız, onu bağımlılık olarak eklersiniz. Sbt için bkz. github.com/spray/spray-json yükleme altında. - Sebastian Ganslandt


Yani, bir hata mesajı ve yanlış örnek kodun yokluğuna bağlı olarak, bu durumun lift-json çıkarmanın nasıl çalıştığını anlamadığı bir konu olduğundan şüpheleniyorum. Yanlış anladım, yorum yap ve bana haber ver. Yani, eğer haklıysam, ihtiyacın olan şey.

Serileştirmek için:

import net.liftweb.json._
  import Extraction._

implicit val formats = DefaultFormats

case class Person(...)
val person = Person(...)
val personJson = decompose(person) // Results in a JValue

Sonra işlemi tersine çevirmek için şöyle bir şey yaparsınız:

// Person Json is a JValue here.
personJson.extract[Person]

Sorun yaşadığınız kısım değilse, bana haber verin ve cevabımı daha faydalı olması için gözden geçirmeyi deneyebilirim.


2
2017-10-01 03:23



Sorunun Scala 2.10'un ikili uyumluluğu bozduğuna ve lift-json'un şu anda güncel olmadığına inanıyorum. - Kipton Barros
2.10 için lift-json artık mevcut ve güncel! Şimdi benim için iyi çalışıyor. bunu gör: liftweb.net/25 - jpswain