簡體   English   中英

JSON轉換為case類,並使用json4s進行泛型解碼

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM