哪个JSON序列化库适合以下情况?
我有以下情况: 我想序列化Scala case类,这些类使用java.util.UUID类型的var扩展父类。 本案例类的序列化应该在没有任何配置的情况下进行——没有注释和自定义格式的定义。任何序列化提示都可以位于父类中 我尝试了sjson,但基于反射的序列化无法序列化UUID类型,基于类型的序列化迫使我为每个案例类定义格式。哪个JSON序列化库适合以下情况?,json,scala,Json,Scala,我有以下情况: 我想序列化Scala case类,这些类使用java.util.UUID类型的var扩展父类。 本案例类的序列化应该在没有任何配置的情况下进行——没有注释和自定义格式的定义。任何序列化提示都可以位于父类中 我尝试了sjson,但基于反射的序列化无法序列化UUID类型,基于类型的序列化迫使我为每个案例类定义格式。 哪个json序列化库最适合这种情况 如果类型很重要,您应该查看YAML 它是json的一个子集,具有改进的功能,比如变量类型。这里有一个解决方案 它打印: {"uuid
哪个json序列化库最适合这种情况 如果类型很重要,您应该查看YAML 它是json的一个子集,具有改进的功能,比如变量类型。这里有一个解决方案 它打印:
{"uuid":{"mostSig":-8054689529719995935,"leastSig":-5722404370736228056},"name":"foo"}'
对父类型使用自定义序列化程序的另一个解决方案
sealed abstract class Parent {
var uuid: UUID = UUID.randomUUID
}
case class Foo(name: String) extends Parent
object UUIDTest extends Application {
implicit val formats =
Serialization.formats(NoTypeHints) + new ParentSerializer
val f = Foo("foo")
val ser = write(f)
println(ser)
val f2 = read[Foo](ser)
assert(f == f2)
// Special serializer for Parent type
class ParentSerializer extends Serializer[Parent] {
def deserialize(implicit format: Formats): PartialFunction[(TypeInfo, JValue), Parent] = {
case (t@TypeInfo(cl, _), json) if (classOf[Parent].isAssignableFrom(cl)) =>
val x = Extraction.extract(json, t)(DefaultFormats).asInstanceOf[Parent]
x.uuid = (for {
JField("mostSig", JInt(m)) <- json
JField("leastSig", JInt(l)) <- json
} yield new UUID(m.longValue, l.longValue)).head
x
}
def serialize(implicit format: Formats): PartialFunction[Any, JValue] = {
case x: Parent =>
Extraction.decompose(x)(DefaultFormats) ++
JField("mostSig", x.uuid.getMostSignificantBits) ++
JField("leastSig", x.uuid.getLeastSignificantBits)
}
}
}
密封抽象类父类{
变量uuid:uuid=uuid.randomUUID
}
案例类Foo(名称:String)扩展了父类
对象UUIDTest扩展应用程序{
隐式val格式=
Serialization.formats(NotypeHits)+新的ParentSerializer
val f=Foo(“Foo”)
val ser=写入(f)
println(ser)
val f2=读取[Foo](ser)
断言(f==f2)
//父类型的特殊序列化程序
类ParentSerializer扩展序列化程序[Parent]{
def反序列化(隐式格式:格式):PartialFunction[(TypeInfo,JValue),Parent]={
案例(t@TypeInfo(cl,z),json)if(classOf[Parent].isAssignableFrom(cl))=>
val x=Extraction.extract(json,t)(DefaultFormats).asInstanceOf[Parent]
x、 uuid=(对于{
JField(“mostSig”,JInt(m))尝试包含JSON支持的库。我在几个项目中成功地使用了它。它有许多默认转换器,包括一个用于java.util.UUID
。默认转换器的完整列表位于此处:
这里有一个关于使用XStream进行JSON读写的简短教程:。教程代码是为Java编写的,但对Scala来说应该是一样的,因为反射是在后台使用的
请记住,序列化然后反序列化对象的任意图形并不总是可以使用此库。特别是,无法处理数据中的循环,即数据必须是纯层次结构树。考虑到JSON格式的意图,这是一个合理的限制
参考链接:
XStream JSON教程:
XStream默认转换器:您可以尝试jerkson:
它对我的使用很好,但主要是列表/映射结构。如果它支持您的需求,我也不会感到惊讶
编辑:用下面的例子(受另一个答案中的提升例子的启发)尝试一下。似乎效果不错
import java.util.UUID
import com.codahale.jerkson.Json
import org.scalatest.FunSuite
sealed abstract class Parent {
def uuid: UUID
}
case class Foo(uuid: UUID, name: String) extends Parent
class TmpJsonTest extends FunSuite {
test("Json case class serialize") {
val f = Foo(UUID.randomUUID, "foo")
val ser = Json.generate(f)
println(ser)
val f2 = Json.parse[Foo](ser)
assert(f === f2)
}
}
YAML实际上是JSON的超集。您的代码与我的案例并不完全相似。类父级中的uuid应该是var,类Foo(case-class Foo(name:String)扩展父级)中应该缺少uuid。那么提升JSON会起作用吗?否:(Lift JSON序列化仅适用于案例类构造函数参数。内部字段未序列化。Wojciech,我添加了另一个可能适用于您的解决方案。它为父类型添加了自定义序列化程序。
import java.util.UUID
import com.codahale.jerkson.Json
import org.scalatest.FunSuite
sealed abstract class Parent {
def uuid: UUID
}
case class Foo(uuid: UUID, name: String) extends Parent
class TmpJsonTest extends FunSuite {
test("Json case class serialize") {
val f = Foo(UUID.randomUUID, "foo")
val ser = Json.generate(f)
println(ser)
val f2 = Json.parse[Foo](ser)
assert(f === f2)
}
}