使用Lift-Json和Case Classes

时间:2014-08-14 03:17:39

标签: json scala lift mailgun lift-json

我似乎无法为这个特定的Json有效负载编写正确的case类。我相信它与数组中的第一个索引有关,它没有关键字符串。关于如何解决这个问题的任何想法?作为参考,我使用的是Scala 2.10.4,Akka 2.3.2,Spray 1.3.1和Lift-Json 2.6。我试图提取的Json来自Mailgun's Events API编辑:核心问题是如何提取到Json中没有键的案例类?我的代码如下:

import net.liftweb.json._

case class Paging(next : String, previous : String)
case class DeliveryEnvelope(transport : String, sender : String, `sending-ip` : String)
case class DeliveryIndex(tags : List[String], envelope : DeliveryEnvelope)
case class DeliveryStatus(message : String, code : Int, description : String)
case class Flags(`is-authenticated` : Boolean, `is-test-mode` : Boolean)
case class DeliveryMessage(headers : Headers, attachments : Option[List[Object]], recipients : List[String], size : Long)
case class Headers(to : String, `message-id` : String, from : String, subject : String)
case class DeliveryData(index : DeliveryIndex, `delivery-status` : DeliveryStatus,
                    campaigns : List[String], `user-variables` : Object, flags : Flags, timestamp : Double,
                    message : DeliveryMessage, recipient : String, event : String)
case class Delivered(items: List[DeliveryData], paging: Paging)

object Main extends App {
  implicit val formats = DefaultFormats

val json = parse(
""" {
  "items": [
    {
      "tags": [],
      "envelope": {
        "transport": "smtp",
        "sender": "postmaster@samples.mailgun.org",
        "sending-ip": "184.173.153.199"
      },
      "delivery-status": {
        "message": "",
        "code": 0,
        "description": null
      },
      "campaigns": [],
      "user-variables": {},
      "flags": {
        "is-authenticated": true,
        "is-test-mode": false
      },
      "timestamp": 1377208314.173742,
      "message": {
        "headers": {
          "to": "recipient@example.com",
          "message-id": "20130822215151.29325.59996@samples.mailgun.org",
          "from": "sender@example.com",
          "subject": "Sample Message"
        },
        "attachments": [],
        "recipients": [
          "recipient@example.com"
        ],
        "size": 31143
      },
      "recipient": "recipient@example.com",
      "event": "delivered"
    }
  ],
  "paging": {
    "next": "https://api.mailgun.net/v2/samples.mailgun.org/events/W3siYiI6ICIy",
    "previous": "https://api.mailgun.net/v2/samples.mailgun.org/events/W3siYiI6"
  }
} """)
println(compactRender(json))
println(json.extract[Delivered])

输出:

{"items":[{"tags":[],"envelope":{"transport":"smtp","sender":"postmaster@samples.mailgun.org","sending-ip":"184.173.153.199"},"delivery-status":{"message":"","code":0,"description":null},"campaigns":[],"user-variables":{},"flags":{"is-authenticated":true,"is-test-mode":false},"timestamp":1.377208314173742E9,"message":{"headers":{"to":"recipient@example.com","message-id":"20130822215151.29325.59996@samples.mailgun.org","from":"sender@example.com","subject":"Sample Message"},"attachments":[],"recipients":["recipient@example.com"],"size":31143},"recipient":"recipient@example.com","event":"delivered"}],"paging":{"next":"https://api.mailgun.net/v2/samples.mailgun.org/events/W3siYiI6ICIy","previous":"https://api.mailgun.net/v2/samples.mailgun.org/events/W3siYiI6"}}
Exception in thread "main" net.liftweb.json.MappingException: No usable value for items
No usable value for index
No usable value for envelope
No usable value for transport
Did not find value which can be converted into java.lang.String
   at net.liftweb.json.Meta$.fail(Meta.scala:191)
   at net.liftweb.json.Extraction$.mkValue$1(Extraction.scala:357)
   at net.liftweb.json.Extraction$.net$liftweb$json$Extraction$$build$1(Extraction.scala:317)
   at net.liftweb.json.Extraction$$anonfun$14.apply(Extraction.scala:253)
   at net.liftweb.json.Extraction$$anonfun$14.apply(Extraction.scala:253)
   at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
   at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
   at scala.collection.immutable.List.foreach(List.scala:318)
   at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
   at scala.collection.AbstractTraversable.map(Traversable.scala:105)
   at net.liftweb.json.Extraction$.instantiate$1(Extraction.scala:253)
   at net.liftweb.json.Extraction$.newInstance$1(Extraction.scala:286)
   at net.liftweb.json.Extraction$.net$liftweb$json$Extraction$$build$1(Extraction.scala:315)
   at net.liftweb.json.Extraction$.net$liftweb$json$Extraction$$extract0(Extraction.scala:366)
   at net.liftweb.json.Extraction$.net$liftweb$json$Extraction$$extract0(Extraction.scala:199)
   at net.liftweb.json.Extraction$.extract(Extraction.scala:43)
   at net.liftweb.json.JsonAST$JValue.extract(JsonAST.scala:312)
   at Main$delayedInit$body.apply(Main.scala:87)
   at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
   at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
   at scala.App$$anonfun$main$1.apply(App.scala:71)
   at scala.App$$anonfun$main$1.apply(App.scala:71)
   at scala.collection.immutable.List.foreach(List.scala:318)
   at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:32)
   at scala.App$class.main(App.scala:71)
   at Main$.main(Main.scala:30)
   at Main.main(Main.scala)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
   at java.lang.reflect.Method.invoke(Method.java:606)
   at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: net.liftweb.json.MappingException: No usable value for index
No usable value for envelope
No usable value for transport
Did not find value which can be converted into java.lang.String
   at net.liftweb.json.Meta$.fail(Meta.scala:191)
   at net.liftweb.json.Extraction$.mkValue$1(Extraction.scala:357)
   at net.liftweb.json.Extraction$.net$liftweb$json$Extraction$$build$1(Extraction.scala:317)
   at net.liftweb.json.Extraction$$anonfun$14.apply(Extraction.scala:253)
   at net.liftweb.json.Extraction$$anonfun$14.apply(Extraction.scala:253)
   at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
   at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
   at scala.collection.immutable.List.foreach(List.scala:318)
   at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
   at scala.collection.AbstractTraversable.map(Traversable.scala:105)
   at net.liftweb.json.Extraction$.instantiate$1(Extraction.scala:253)
   at net.liftweb.json.Extraction$.newInstance$1(Extraction.scala:286)
   at net.liftweb.json.Extraction$.net$liftweb$json$Extraction$$build$1(Extraction.scala:315)
   at net.liftweb.json.Extraction$$anonfun$21.apply(Extraction.scala:305)
   at net.liftweb.json.Extraction$$anonfun$21.apply(Extraction.scala:305)
   at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
   at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
   at scala.collection.immutable.List.foreach(List.scala:318)
   at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
   at scala.collection.AbstractTraversable.map(Traversable.scala:105)
   at net.liftweb.json.Extraction$.newCollection$1(Extraction.scala:305)
   at net.liftweb.json.Extraction$.net$liftweb$json$Extraction$$build$1(Extraction.scala:322)
   at net.liftweb.json.Extraction$.mkValue$1(Extraction.scala:351)
... 30 more
Caused by: net.liftweb.json.MappingException: No usable value for envelope
No usable value for transport
Did not find value which can be converted into java.lang.String
   at net.liftweb.json.Meta$.fail(Meta.scala:191)
   at net.liftweb.json.Extraction$.mkValue$1(Extraction.scala:357)
   at net.liftweb.json.Extraction$.net$liftweb$json$Extraction$$build$1(Extraction.scala:317)
   at net.liftweb.json.Extraction$$anonfun$14.apply(Extraction.scala:253)
   at net.liftweb.json.Extraction$$anonfun$14.apply(Extraction.scala:253)
   at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
   at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
   at scala.collection.immutable.List.foreach(List.scala:318)
   at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
   at scala.collection.AbstractTraversable.map(Traversable.scala:105)
   at net.liftweb.json.Extraction$.instantiate$1(Extraction.scala:253)
   at net.liftweb.json.Extraction$.newInstance$1(Extraction.scala:286)
   at net.liftweb.json.Extraction$.net$liftweb$json$Extraction$$build$1(Extraction.scala:315)
   at net.liftweb.json.Extraction$.mkValue$1(Extraction.scala:351)
... 51 more
Caused by: net.liftweb.json.MappingException: No usable value for transport
Did not find value which can be converted into java.lang.String
   at net.liftweb.json.Meta$.fail(Meta.scala:191)
   at net.liftweb.json.Extraction$.mkValue$1(Extraction.scala:357)
   at net.liftweb.json.Extraction$.net$liftweb$json$Extraction$$build$1(Extraction.scala:317)
   at net.liftweb.json.Extraction$$anonfun$14.apply(Extraction.scala:253)
   at net.liftweb.json.Extraction$$anonfun$14.apply(Extraction.scala:253)
   at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
   at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
   at scala.collection.immutable.List.foreach(List.scala:318)
   at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
   at scala.collection.AbstractTraversable.map(Traversable.scala:105)
   at net.liftweb.json.Extraction$.instantiate$1(Extraction.scala:253)
   at net.liftweb.json.Extraction$.newInstance$1(Extraction.scala:286)
   at net.liftweb.json.Extraction$.net$liftweb$json$Extraction$$build$1(Extraction.scala:315)
   at net.liftweb.json.Extraction$.mkValue$1(Extraction.scala:351)
... 63 more
Caused by: net.liftweb.json.MappingException: Did not find value which can be converted into java.lang.String
   at net.liftweb.json.Meta$.fail(Meta.scala:191)
   at net.liftweb.json.Extraction$.convert(Extraction.scala:403)
   at net.liftweb.json.Extraction$.net$liftweb$json$Extraction$$build$1(Extraction.scala:314)
   at net.liftweb.json.Extraction$.mkValue$1(Extraction.scala:351)
... 75 more

2 个答案:

答案 0 :(得分:2)

感谢大家贡献(或只是查看)我的问题。我通过循环遍历Json的数据部分解决了我的问题。

val json = parse(STRING HERE)
      val elements = (json \\ "items").children
      for(item <- elements) {
        val data = item.extract[ClickData]

希望这可以帮助其他人解决这个或类似的问题。

答案 1 :(得分:0)

您正在将每个项目映射到DeliveryData的实例,但在DeliveryData:

  • 您有一个非可选索引字段,相应的JSON中没有值。如果该值是可选的,则应将其定义为Option [DeliveryIndex]
  • 您没有字段来映射JSON中包含的信封信息。您已创建了DeliveryEnvelope案例类,但它仅由DeliveryIndex类引用,并且索引字段不存在于您发布的JSON中。