Scala 2.10 + Json 序列化和反序列化
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12591457/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Scala 2.10 + Json serialization and deserialization
提问by user1698607
Scala 2.10 seems to have broken some of the old libraries (at least for the time being) like Jerkson and lift-json.
Scala 2.10 似乎已经破坏了一些旧库(至少目前是这样),例如 Jerkson 和lift-json。
The target usability is as follows:
目标可用性如下:
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)
But I'm having trouble finding good existing ways of generating and deserializing Json that work with Scala 2.10.
但是我很难找到生成和反序列化适用于 Scala 2.10 的 Json 的良好现有方法。
Are there best practice ways of doing this in Scala 2.10?
在 Scala 2.10 中有这样做的最佳实践方法吗?
回答by Kipton Barros
Hymansonis a Java library to process JSON fast. The Jerkson project wraps Hymanson, but appears to be abandoned. I've switched to Hymanson's Scala Modulefor serialization and deserialization to native Scala data structures.
Hymanson是一个用于快速处理 JSON 的 Java 库。Hyman森项目包装了Hyman逊,但似乎被放弃了。我已经切换到 Hymanson 的Scala 模块,用于对原生 Scala 数据结构进行序列化和反序列化。
To get it, include the following in your build.sbt:
要获得它,请在您的build.sbt:
libraryDependencies ++= Seq(
"com.fasterxml.Hymanson.module" %% "Hymanson-module-scala" % "2.1.3",
...
)
Then your examples will work verbatim with the following Hymanson wrapper (I extracted it from Hymanson-module-scala test files):
然后,您的示例将使用以下 Hymanson 包装器逐字运行(我从 Hymanson-module-scala 测试文件中提取了它):
import java.lang.reflect.{Type, ParameterizedType}
import com.fasterxml.Hymanson.databind.ObjectMapper
import com.fasterxml.Hymanson.module.scala.DefaultScalaModule
import com.fasterxml.Hymanson.annotation.JsonProperty;
import com.fasterxml.Hymanson.core.`type`.TypeReference;
object HymansonWrapper {
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
}
}
}
Other Scala 2.10 JSON options include Twitter's scala-jsonbased on the Programming Scala book--it's simple, at the cost of performance. There is also spray-json, which uses parboiledfor parsing. Finally, Play's JSON handlinglooks nice, but it does not easily decouple from the Play project.
其他 Scala 2.10 JSON 选项包括 Twitter 的基于 Scala 编程书籍的scala-json——它很简单,但以性能为代价。还有Spray-json,它使用parboiled进行解析。最后,Play 的 JSON 处理看起来不错,但它并不容易与 Play 项目分离。
回答by Johan Prinsloo
回答by simbo1905
I can heartily recommend argonautfor json support in scala. All you need to configure it to serialize your Customer object is one line:
我可以衷心推荐argonaut在 Scala 中提供 json 支持。配置它以序列化 Customer 对象所需的全部内容是一行:
implicit lazy val CodecCustomer: CodecJson[Customer] =
casecodec6(Customer.apply, Customer.unapply)("id","name","address","city","state","user_id")
That will pimp your class to give it an .asJsonmethod which turns it into a string. It will also pimp the string class to give it a method .decodeOption[List[Customer]]to parse strings. It handles the options in your class fine. Here is a working class with a passing test and a running main method which you can drop into a git clone of argonaut to see it all working fine:
这将拉皮条你的班级给它一个.asJson方法,把它变成一个字符串。它还将对字符串类进行拉皮条,为其提供.decodeOption[List[Customer]]解析字符串的方法。它可以很好地处理您班级中的选项。这是一个通过测试和正在运行的 main 方法的工作类,您可以将其放入 argonaut 的 git clone 中以查看它是否正常工作:
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}")
}
}
The developers are also helpful and responsive to folks getting started.
开发人员也乐于助人,并且对人们的入门做出回应。
回答by Sebastian Ganslandt
There is now a fork of Jerkson that supports Scala 2.10 at https://github.com/randhindi/jerkson.
现在在https://github.com/randhindi/jerkson有一个支持 Scala 2.10 的 Jerkson 分支。
回答by Matt Farmer
So, based on the absence of an error message and the incorrect sample code, I'm suspecting this is more of an issue of just not understanding how the lift-json extraction works. If I've misunderstood, do comment and let me know. So, if I'm right then here's what you need.
因此,基于没有错误消息和不正确的示例代码,我怀疑这更多是一个不了解 Lift-json 提取如何工作的问题。如果我误解了,请发表评论并让我知道。所以,如果我是对的,那么这就是你需要的。
To serialize:
序列化:
import net.liftweb.json._
import Extraction._
implicit val formats = DefaultFormats
case class Person(...)
val person = Person(...)
val personJson = decompose(person) // Results in a JValue
Then to reverse the process you'd do something like:
然后要反转该过程,您可以执行以下操作:
// Person Json is a JValue here.
personJson.extract[Person]
If that's not the part you're having trouble with, then do let me know and I can try to revise my answer to be more helpful.
如果这不是您遇到问题的部分,请告诉我,我可以尝试修改我的答案以提供更多帮助。

