首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将lift-json提取到具有上界的case类中。

将lift-json提取到具有上界的case类中。
EN

Stack Overflow用户
提问于 2010-11-03 16:45:44
回答 1查看 4.4K关注 0票数 6

我花了最后一天搜索和阅读各种网站和文章,试图找到这个问题的答案,但我没有发现任何帮助。我甚至不确定这是否可行。我的问题是,我正在尝试使用lift-json解析和提取Json响应。响应由4部分组成,其中前3部分对于我提出的每种请求的每个响应都是相同的。最后一部分会根据请求的类型而变化,但是它总是会是某种类型的列表。我希望做这样的事:

代码语言:javascript
运行
复制
abstract class MyObjects
case class Apple(id: Int, name: String, color: String) extends MyObjects
case class Orange(id: Long, name: String, state: String) extends MyObjects

abstract class MyResponse
case class Fruits[T <: MyObjects](aisle: Int, bin: Int, hasWhat: Option[List[T]])

如果我想知道所有的苹果是什么,我会提出一个要求,并得到一个回应的苹果列表。当我试图提取这个示例时:

代码语言:javascript
运行
复制
myJson.extract[Fruits[Apple]]

我知道这个错误:

代码语言:javascript
运行
复制
net.liftweb.json.MappingException: do not know how to get type parameter from T
    at net.liftweb.json.Meta$.fail(Meta.scala:128)
    at net.liftweb.json.Meta$Reflection$.term$1(Meta.scala:206)
    at net.liftweb.json.Meta$Reflection$.typeParameters(Meta.scala:220)
    at net.liftweb.json.Meta$.mkContainer$1(Meta.scala:91)
    at net.liftweb.json.Meta$.fieldMapping$1(Meta.scala:101)
    at net.liftweb.json.Meta$.mkContainer$1(Meta.scala:90)
    at net.liftweb.json.Meta$.fieldMapping$1(Meta.scala:107)
    at net.liftweb.json.Meta$.toArg$1(Meta.scala:117)
    at net.liftweb.json.Meta$$anonfun$constructors$1$1$$anonfun$apply$1.apply(Meta.scala:83)
    at net.liftweb.json.Meta$$anonfun$constructors$1$1$$anonfun$apply$1.apply(Meta.scala:82)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:...

我使用的是lift-json2.1和Scala2.8。我确实有办法解决这个问题,具体地为每种类型的响应创建一个案例类,但我认为我想做的更干净。我只想知道a)这可能吗?( b)若然,我做错了什么?

EDIT...sample应用程序:

代码语言:javascript
运行
复制
val apples = """{ "aisle" : 1, "bin" : 1,
            "hasWhat" : [{ "id" : 4, "name" : "Granny", "color" : "green"}, 
                         { "id" : 4, "name" : "Fuji", "color" : "red"}] }"""

val oranges = """ { "aisle" : 3, "bin" : 2, 
             "hasWhat" : [{ "id" : 2, "name" : "Navel", "state" : "FL" }, 
                         { "id" : 2, "name" : "Clementine", "state" : "Spain" }]}"""

scala> val aJson = parse(apples)
aJson: net.liftweb.json.JsonAST.JValue = JObject(List(JField(aisle,JInt(1)), JField(bin,JInt(1)), JField(hasWhat,JArray(List(JObject(List(JField(id,JInt(4)), JField(name,JString(Granny)), JField(color,JString(green)))), JObject(List(JField(id,JInt(4)), JField(name,JString(Fuji)), JField(color,JString(red)))))))))

scala> val oJson = parse(oranges)
oJson: net.liftweb.json.JsonAST.JValue = JObject(List(JField(aisle,JInt(3)), JField(bin,JInt(2)), JField(hasWhat,JArray(List(JObject(List(JField(id,JInt(2)), JField(name,JString(Navel)), JField(state,JString(FL)))))))))

scala> val doesntWork = aJson.extract[Fruits]
doesntWork: org.spin.node.gogrid.objects.Fruits = Fruits(1,1,None)

scala> val works = aJson.extract[AFruit]
works: org.spin.node.gogrid.objects.AFruit = AFruit(1,1,Some(List(Apple(4,Granny,green), Apple(4,Fuji,red))))

我希望doesntWork像作品一样,在这里:

代码语言:javascript
运行
复制
case class AFruit(aisle: Int, bin: Int, hasWhat: Option[List[Apple]])

谢谢!-newbie

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-11-03 17:42:16

还不支持提取参数化案例类。一个解决方法(但不确定这是否适用于您的情况)是将成果作为一个具体类型,并将类型信息添加到JSON中。

代码语言:javascript
运行
复制
import net.liftweb.json._
import net.liftweb.json.Extraction._
import net.liftweb.json.JsonAST._
import net.liftweb.json.Printer._

abstract class MyObjects
case class Apple(id: Int, name: String, color: String) extends MyObjects
case class Orange(id: Long, name: String, state: String) extends MyObjects

case class Fruits(aisle: Int, bin: Int, hasWhat: Option[List[MyObjects]])

object Test extends Application {
  // This configuration adds an extra field for MyObjects to JSON
  // which tells the real type of a MyObject.
  implicit val formats = Serialization.formats(FullTypeHints(List(classOf[MyObjects])))

  val fs = Fruits(0, 0, Some(List(
    Apple(1, "Granny Smith", "green"), 
    Apple(2, "Grenade", "red"))))
  val json = decompose(fs)
  println(pretty(render(json)))

  assert (json.extract[Fruits] == fs)
}

指纹:

代码语言:javascript
运行
复制
{
  "aisle":0,
  "bin":0,
  "hasWhat":[{
    "jsonClass":"Apple",
    "id":1,
    "name":"Granny Smith",
    "color":"green"
  },{
    "jsonClass":"Apple",
    "id":2,
    "name":"Grenade",
    "color":"red"
  }]
}
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4089409

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档