【问题标题】:Using Lift-Json with Case Classes将 Lift-Json 与案例类一起使用
【发布时间】:2014-10-07 14:22:05
【问题描述】:

我似乎无法为这个特定的 Json 有效负载编写适当的案例类。我相信它与数组中的第一个索引有关,它没有键字符串。关于如何解决这个问题的任何想法?作为参考,我使用的是 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

【问题讨论】:

    标签: json scala lift mailgun lift-json


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 谢谢,但我确实忘记提到 DeliveryIndex 只是为了让它发挥作用而进行的几次尝试中的最新一次。我认为核心问题归结为在没有键的情况下提取第一个索引(标签、信封),因为 Lift-Json 使用这些键进行提取。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-11
      • 2011-11-08
      • 2020-11-16
      相关资源
      最近更新 更多