[英]JSON to case class with generics decoding with json4s
我正在嘗試使用json4s構建json來區分大小寫類en / decoder。使用泛型icw清單似乎適用於普通類型/類,但是更復雜的配置似乎失敗了。
如何結合使用json4s和從json字符串中提取更復雜的類型?
import org.json4s._
import org.json4s.native.JsonMethods._
implicit val formats = org.json4s.DefaultFormats
case class User(name:String)
case class Product(id:String)
case class Meta(count:Int)
case class ResultList[T: Manifest](meta: Meta, result: List[T])
// Without generics
case class ResultListUser(meta: Meta, result: List[User])
case class ResultListProduct(meta: Meta, result: List[Product])
// general decode method
def decode[T: Manifest](jsonStr: String): T = {
parse(jsonStr).extract[T]
}
// data
val userJson = """{"meta":{"count":2},"result":[{"name":"Tom"},{"name":"Lucas"}]}"""
val productJson = """{"meta":{"count":2},"result":[{"id":"123"},{"id":"456"}]}"""
val resultListUser = decode[ResultListUser](userJson)
resultListUser:ResultListUser = ResultListUser(Meta(2),List(User(Tom),User(Lucas)))
val resultListProduct = decode[ResultListProduct](productJson)
resultListProduct:ResultListProduct = ResultListProduct(Meta(2),List(Product(123),Product(456)))
val resultListUser2 = decode[ResultList[User]](userJson)
org.json4s.package $ MappingException:沒有可用的證據$ 1
沒有Manifest [User]類型的構造函數,JNothing
...
val resultListProduct2 = decode[ResultList[Product]](productJson)
org.json4s.package $ MappingException:沒有可用的證據值$ 1沒有Manifest [Product]類型的構造方法,JNothing在org.json4s.reflect.package $ .fail(/ Users / tomlous / Development / Scala / testjes / src / main /scala/json4sgenerics.sc:91),位於org.json4s.Extraction $ ClassInstanceBuilder.org $ json4s $ Extraction $ ClassInstanceBuilder $$ buildCtorArg(/Users/tomlous/Development/Scala/testjes/src/main/scala/json4sgenerics.sc: 522)在org.json4s.Extraction $ ClassInstanceBuilder $$ anonfun $ 15.apply(/Users/tomlous/Development/Scala/testjes/src/main/scala/json4sgenerics.sc:542)在org.json4s.Extraction $ ClassInstanceBuilder $$ anonfun $ 15.apply(/Users/tomlous/Development/Scala/testjes/src/main/scala/json4sgenerics.sc:542)在scala.collection.TraversableLike $$ anonfun $ map $ 1.apply(/Users/tomlous/Development/Scala/testjes/src/main/scala/json4sgenerics.sc:542) Scala / testjes / src / main / scala / json4sgenerics.sc:230)位於scala.collection.TraversableLike $$ anonfun $ map $ 1.apply(/ Users / tomlous / Development / Scala / testjes / src / main / scala / json4sgenerics。 sc:230)在scala.collection.mutabl e.ResizableArray $ class.foreach(/Users/tomlous/Development/Scala/testjes/src/main/scala/json4sgenerics.sc:55)在scala.collection.mutable.ArrayBuffer.foreach(/ Users / tomlous / Development / Scala /testjes/src/main/scala/json4sgenerics.sc:44)位於scala.collection.TraversableLike $ class.map(/Users/tomlous/Development/Scala/testjes/src/main/scala/json4sgenerics.sc:230) scala.collection.AbstractTraversable.map(/Users/tomlous/Development/Scala/testjes/src/main/scala/json4sgenerics.sc:100)位於org.json4s.Extraction $ ClassInstanceBuilder.instantiate(/ Users / tomlous / Development / Scala /testjes/src/main/scala/json4sgenerics.sc:542)位於org.json4s.Extraction $ ClassInstanceBuilder.result(/Users/tomlous/Development/Scala/testjes/src/main/scala/json4sgenerics.sc:593) org.json4s.Extraction $$ anonfun $ extract $ 6.apply(/Users/tomlous/Development/Scala/testjes/src/main/scala/json4sgenerics.sc:396)在org.json4s.Extraction $$ anonfun $ extract $ 6。申請(/用戶/ tomlous /開發/斯卡拉/ testjes / src目錄/主/斯卡拉/ json4sgeneric s.sc:388),位於org.json4s.Extraction $ .customOrElse(/Users/tomlous/Development/Scala/testjes/src/main/scala/json4sgenerics.sc:602),位於org.json4s.Extraction $ .extract(/ Users / tomlous / Development / Scala / testjes / src / main / scala / json4sgenerics.sc:388)在worksheet.worksheet(/Users/tomlous/Development/Scala/testjes/src/main/scala/json4sgenerics.sc:35)
由以下原因引起:org.json4s.package $ MappingException:類型Manifest [Product]沒有構造函數,org.json4s.reflect.package $ .fail(package.scala:95)處的JNothing在org.json4s.Extraction $ ClassInstanceBuilder $$ anonfun $ org $ json4s $ Extraction $ ClassInstanceBuilder $$ constructor $ 1.apply(Extraction.scala:477)在org.json4s.Extraction $ ClassInstanceBuilder $$ anonfun $ org $ json4s $ Extraction $ ClassInstanceBuilder $$ constructor $ 1.apply(Extraction.scala :477)在scala.Option.getOrElse(Option.scala:121)在org.json4s.Extraction $ ClassInstanceBuilder.org $ json4s $ Extraction $ ClassInstanceBuilder $$ constructor(Extraction.scala:477)在org.json4s.Extraction $ ClassInstanceBuilder org.json4s上的.instantiate(Extraction.scala:532).org.json4s上的Extraction $ ClassInstanceBuilder.result(Extraction.scala:597).org上的Extraction $$ anonfun $ extract $ 6.apply(Extraction.scala:400)。 org.json4s.Extraction $ .customOrElse(Extraction.scala:606)的json4s.Extraction $$ anonfun $ extract $ 6.apply(Extraction.scala:392)在org.json4s.Extraction $ .extract(Ex org.json4s.Extraction $ ClassInstanceBuilder.org $ json4s $ Extraction $ ClassInstanceBuilder $$ buildCtorArg(Extraction.scala:514)在org.json4s.Extraction $ ClassInstanceBuilder $$ anonfun $ 15.apply(Extraction.scala) :546)在org.json4s.Extraction $ ClassInstanceBuilder $$ anonfun $ 15.apply(Extraction.scala:546)在scala.collection.TraversableLike $$ anonfun $ map $ 1.apply(TraversableLike.scala:234)在scala.collection。在scala.collection.mutable.ResizableArray $ class.foreach(ResizableArray.scala:59)處的TraversableLike $$ anonfun $ map $ 1.apply(TraversableLike.scala:234)在scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala: 48)在scala.collection.TraversableLike $ class.map(TraversableLike.scala:234)在scala.collection.AbstractTraversable.map(Traversable.scala:104)在org.json4s.Extraction $ ClassInstanceBuilder.instantiate(Extraction.scala:546) )在org.json4s.Extraction $ ClassInstanceBuilder.result(Extraction.scala:597)在org.json4s.Extraction $$ anonfun $ extract $ 6.apply(Extraction.scala:4 00)在org.json4s.Extraction $$ anonfun $ extract $ 6.apply(Extraction.scala:392)在org.json4s.Extraction $ .customOrElse(Extraction.scala:606)在org.json4s.Extraction $ .extract(Extraction .scala:392)位於org.json4s.Extraction $ .extract(Extraction.scala:39)位於org.json4s.ExtractableJsonAstNode.extract(ExtractableJsonAstNode.scala:21)位於A $ A7 $ A $ A7.decode(json4sgenerics.sc :24)在A $ A7 $ A $ A7.resultListProduct2 $ lzycompute(json4sgenerics.sc:37)在A $ A7 $ A $ A7.resultListProduct2(json4sgenerics.sc:37)在A $ A7 $ A $ A7.get $ $ instance $$ resultListProduct2(json4sgenerics.sc:36)位於A $ A7 $ .main(json4sgenerics.sc:92)位於A $ A7.main(json4sgenerics.sc)在sun.reflect.NativeMethodAccessorImpl.invoke0(本地方法)位於org.jetbrains的java.lang.reflect.Method.invoke(Method.java:497)處的sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)處的sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) .plugins.scala.worksheet.MyWorksheetRunner.main(MyWorksheetRunner.java:22)
問題是您確實希望將Manifest
傳遞給decode
但您可能不希望將其傳遞給
case class ResultList[T: Manifest](meta: Meta, result: List[T])
問題是該代碼實際上已編譯為類似
case class ResultList[T](meta: Meta, result: List[T])(implicit evidence: Manifest[T])
而且這個implicit
參數evidence
正是json4s無法弄清楚如何從JSON提供給您的(這時它也不能使用隱式解析,因為它僅在編譯時完成)。
因此,如果將ResultList
更改為
case class ResultList[T](meta: Meta, result: List[T])
我希望只要T
綁定到Json4s可以提取的內容,您的代碼就可以工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.