Scala 2.10似乎打破了一些旧的库(至少目前为止),比如Jerkson和lift-json.
目标可用性如下:
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)
Run Code Online (Sandbox Code Playgroud)
但是我很难找到适用于Scala 2.10的Json生成和反序列化的现有方法.
在Scala 2.10中有最佳实践方法吗?
如果我打电话,有一个jString : JString持有"abc"字符串的值.我该如何获得?"JString(abc)" : StringjString.toString"abc" : String
我试图使用lift-json将JSON提取到case类中.这是我的案例类:
case class Person(name: String, age: Int)
Run Code Online (Sandbox Code Playgroud)
这是json
{ "name": "Some Name", "age": 24, type: "Student" }
Run Code Online (Sandbox Code Playgroud)
如何将type字段提取到实例中Person?
json.extract[Person]
Run Code Online (Sandbox Code Playgroud) 我正在试验json4s库(基于lift-json).我想做的一件事是将JSON字符串解析为AST,然后对其进行操作.
例如,我想要一个字段(如果它不存在则将字段插入AST,或者如果它存在则更新其值).
我无法在文档中找到如何做到这一点.尝试了可用的方法,我提出了以下哪些有效,但感觉很笨拙.
import org.json4s._
import org.json4s.JsonDSL._
import org.json4s.native.JsonMethods._
object TestJson {
  implicit val formats = DefaultFormats
  def main(args: Array[String]): Unit = {
    val json = """{"foo":1, "bar":{"foo":2}}"""
    val ast = parse(json).asInstanceOf[JObject]
    println( upsertField(ast, ("foo" -> "3")) )
    println( upsertField(ast, ("foobar" -> "3")) )
  }
  def upsertField(src:JObject, fld:JField): JValue = {
    if(src \ fld._1 == JNothing){
      src ~ fld
    }
    else{
      src.replace(List(fld._1), fld._2)
    }
  }
}
Run Code Online (Sandbox Code Playgroud)
我不喜欢它有很多原因:
parse(json)转换为JObjectupsertField函数的结果是a JValue,如果我想进一步操作对象,我将不得不重新制作upsertField功能只是感觉很unelegant有没有更好的方法来转换AST? …
我在这里遵循教程并坚持使用json-lift依赖.
这是我的plugings.sbt文件中的依赖项:
addSbtPlugin("net.liftweb" %% "lift-json" % "2.4")
Run Code Online (Sandbox Code Playgroud)
错误是在下面,它似乎是与scala 10.2不兼容的东西,但有人知道我可以得到lift-json使用scala 10.2的方式?
haknick '~/Projects/NickProjects/sometryouts/myscalatrys/scalatra/live-aq-first' --> scala -version
Scala code runner version 2.10.2 -- Copyright 2002-2013, LAMP/EPFL
haknick '~/Projects/NickProjects/sometryouts/myscalatrys/scalatra/live-aq-first' --> scala -version
Scala code runner version 2.10.2 -- Copyright 2002-2013, LAMP/EPFL
haknick '~/Projects/NickProjects/sometryouts/myscalatrys/scalatra/live-aq-first' --> sbt
[info] Loading project definition from /Users/kreshnikmati/Projects/NickProjects/sometryouts/myscalatrys/scalatra/live-aq-first/project
[info] Updating {file:/Users/kreshnikmati/Projects/NickProjects/sometryouts/myscalatrys/scalatra/live-aq-first/project/}default-7238ba...
[info] Resolving net.liftweb#lift-json;2.5 ...
[warn]  module not found: net.liftweb#lift-json;2.5
[warn] ==== typesafe-ivy-releases: tried
[warn]   http://repo.typesafe.com/typesafe/ivy-releases/net.liftweb/lift-json/scala_2.9.2/sbt_0.12/2.5/ivys/ivy.xml
[warn] ==== sbt-plugin-releases: tried
[warn]   http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-releases/net.liftweb/lift-json/scala_2.9.2/sbt_0.12/2.5/ivys/ivy.xml
[warn] ==== local: tried
[warn]   /Users/kreshnikmati/.ivy2/local/net.liftweb/lift-json/scala_2.9.2/sbt_0.12/2.5/ivys/ivy.xml …Run Code Online (Sandbox Code Playgroud) import net.liftweb.json._
import net.liftweb.json.JsonParser._
object test02 extends App {
    implicit val formats = DefaultFormats
    case class User(
        id: Int = 0,
        name: String = "John Doe",
        gender: String = "M")
    val s1=""" {"id":1,"name":"Bill","gender":"M"} """
    var r1=Serialization.read[User](s1)
    println(r1)
    val s2=""" {"id":1} """
    var r2=Serialization.read[User](s2)
    println(r2)  
}
Run Code Online (Sandbox Code Playgroud)
Second Serialization.read导致异常:net.liftweb.json.MappingException:名称没有可用值.
我怎么可能从json读取数据到case类,但是如果缺少某些字段,它们会被case类的默认值替换掉?
考虑以下json:
{
  "type":"A1",
  "system":{
    "path":"/example.org/FooBar",
    "lastModified":"2013-10-01T12:00:00Z"
  },
  "fields":{
    "foo1":["bar1"],
    "foo2":["bar2"],
    "foo3":["bar3"]
  }
}
Run Code Online (Sandbox Code Playgroud)
现在,使用lift-json,我想将此json更改为:
{
  "type":"A1",
  "system":{
    "path":"/example.org/FooBar",
    "lastModified":"2013-10-01T12:00:00Z"
  },
  "fields":{
    "foo1":["bar1"],
    "foo2":["bar2"],
    "foo3":["bar3"]
  },
  "injected":{
    "bar1":"foo1",
    "bar2":"foo2"
  }
}
Run Code Online (Sandbox Code Playgroud)
所以,我尝试了以下内容:
scala> val json = parse("""
     |{
     |  "type":"A1",
     |  "system":{
     |    "path":"/example.org/FooBar",
     |    "lastModified":"2013-10-01T12:00:00Z"
     |  },
     |  "fields":{
     |    "foo1":["bar1"],
     |    "foo2":["bar2"],
     |    "foo3":["bar3"]
     |  }
     |}""")
json: net.liftweb.json.JValue = JObject(List(JField(type,JString(A1)), JField(system,JObject(List(JField(path,JString(/example.org/FooBar)), JField(lastModified,JString(2013-10-01T12:00:00Z))))), JField(fields,JObject(List(JField(foo1,JArray(List(JString(bar1)))), JField(foo2,JArray(List(JString(bar2)))), JField(foo3,JArray(List(JString(bar3)))))))))
scala> json transform{case JObject(l) => JObject(l ::: List(JField("injected", ("bar1" -> "foo1") ~ ("bar2" …Run Code Online (Sandbox Code Playgroud) 我试图使用Lift-Json自动将json对象反序列化为scala类,其中一个坐标类用于存储GeoJson信息.
case class Request(name:String, geometry:Geometry)
sealed abstract class Geometry
case class Point(coordinates:(Double,Double)) extends Geometry
case class LineString(coordinates:List[Point]) extends Geometry
case class Polygon(coordinates:List[LineString]) extends Geometry
Run Code Online (Sandbox Code Playgroud)
我想反序列化一个像这样的json字符串:
{
name:"test",
geometry:{
   "type": "LineString",
   "coordinates": [ [100.0, 0.0], [101.0, 1.0] ]
  }
}
Run Code Online (Sandbox Code Playgroud)
在Geometry字段中使用正确的LineString运行时类进入Request case类.我想我应该使用TypeHint但是怎么样?这是正确的方法还是应该创建三个不同的Request(RequestPoint,RequestLineString和RequestPolygon)?这将是反序列化的Scala代码:
val json = parse(message)
json.extract[Request]
Run Code Online (Sandbox Code Playgroud) 我在scala-salat Google小组中问了这个问题,但几天没有回复,因此在这里尝试.
我有一个案例类,其中包含一个集合Option.
case class SomeClass(
  var name:Option[String]=None,
  var addresses:Option[Set[Address]]=None
)
case class Address(
  var street:Option[String]=None,
  var zip:Option[String]=None
) 
Run Code Online (Sandbox Code Playgroud)
该文档存储在Mongo中就好了.但是,当我尝试使用findOne(有或没有SalatDAO)时,地址字段具有表示地址而不是地址案例类的JSON文本.
因此,Lift-JSON会跳过我的case类中的任何字段Option[Collection[A]].当我删除Option并且只是一起使用时addresses=Set[Address](),它可以工作.但是现在我最终在我的JSON中没有数据的空集,如果消费者删除了条目,我无法找到更新,或者我得到一个空,Set因为消费者没有发送此字段原始请求.
使用Option会将字段设置为None,这意味着我不必担心它是空的或修改的.
任何帮助将不胜感激.
似乎lift-json仅限于以字符串为键的地图.
绕过此限制的最佳方法是什么?