如何使用`lift-json`在scala中反序列化'Either`类型?

问题描述:

如何序列化和反序列化Either类型?如何使用`lift-json`在scala中反序列化'Either`类型?

下面所用的scala控制台lift-json添加到类路径来执行。

case class Thing(location: Either[Location, Address]) 

case class Location(latitude: Double, 
        longitude: Double) 

case class Address(line1: String, 
        line2: String, 
        city: String, 
        state: String, 
        country: String, 
        postalCode: String) 

import net.liftweb.json._ 
import Extraction._ 

implicit val formats = DefaultFormats 

val myThing = Thing(Left(Location(0d, 0d))) 
val asJson = pretty(render(decompose(myThing))) 

产地:

asJson: String = 
{ 
    "location":{ 
    "a":{ 
     "latitude":0.0, 
     "longitude":0.0 
    } 
    } 
} 

然后:

val deserialized = JsonParser.parse(asJson).extract[Thing] 

产地:

net.liftweb.json.MappingException: No usable value for location 
Parsed JSON values do not match with class constructor 
args= 
arg types= 
constructor=public scala.util.Either() 
    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$13.apply(Extraction.scala:253) 
    at net.liftweb.json.Extraction$$anonfun$13.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 .<init>(<console>:22) 
    at .<clinit>(<console>) 
    at .<init>(<console>:7) 
    at .<clinit>(<console>) 
    at $print(<console>) 
    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:601) 
    at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:734) 
    at scala.tools.nsc.interpreter.IMain$Request.loadAndRun(IMain.scala:983) 
    at scala.tools.nsc.interpreter.IMain.loadAndRunReq$1(IMain.scala:573) 
    at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:604) 
    at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:568) 
    at scala.tools.nsc.interpreter.ILoop.reallyInterpret$1(ILoop.scala:756) 
    at scala.tools.nsc.interpreter.ILoop.interpretStartingWith(ILoop.scala:801) 
    at scala.tools.nsc.interpreter.ILoop.command(ILoop.scala:713) 
    at scala.tools.nsc.interpreter.ILoop.processLine$1(ILoop.scala:577) 
    at scala.tools.nsc.interpreter.ILoop.innerLoop$1(ILoop.scala:584) 
    at scala.tools.nsc.interpreter.ILoop.loop(ILoop.scala:587) 
    at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply$mcZ$sp(ILoop.scala:878) 
    at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:833) 
    at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:833) 
    at scala.tools.nsc.util.ScalaClassLoader$.savingContextLoader(ScalaClassLoader.scala:135) 
    at scala.tools.nsc.interpreter.ILoop.process(ILoop.scala:833) 
    at scala.tools.nsc.interpreter.ILoop.main(ILoop.scala:900) 
    at xsbt.ConsoleInterface.run(ConsoleInterface.scala:69) 
    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:601) 
    at sbt.compiler.AnalyzingCompiler.call(AnalyzingCompiler.scala:102) 
    at sbt.compiler.AnalyzingCompiler.console(AnalyzingCompiler.scala:77) 
    at sbt.Console.sbt$Console$$console0$1(Console.scala:23) 
    at sbt.Console$$anonfun$apply$2$$anonfun$apply$1.apply$mcV$sp(Console.scala:24) 
    at sbt.TrapExit$.sbt$TrapExit$$executeMain$1(TrapExit.scala:33) 
    at sbt.TrapExit$$anon$1.run(TrapExit.scala:42) 
Caused by: net.liftweb.json.MappingException: Parsed JSON values do not match with class constructor 
args= 
arg types= 
constructor=public scala.util.Either() 
    at net.liftweb.json.Meta$.fail(Meta.scala:191) 
    at net.liftweb.json.Extraction$.instantiate$1(Extraction.scala:262) 
    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) 
    ... 52 more 

你需要明确枚举类型提示,例如

implicit def formats = DefaultFormats + 
         FullTypeHints(classOf[Either[Location, Address]] :: Nil) 

您需要明确枚举类型提示,例如,

implicit def formats = DefaultFormats + FullTypeHints(classOf[Either[Location, Address]] :: Nil)

确实注意到然而,你需要修复1417 https://github.com/lift/framework/commit/ba2c444076ee6f5dc788bcaab4853b1640b5fef1因为在memoized在此之前没有构造泛型类型和其他Eithers的反序列化将失败

+0

欢迎*上。为了使事情清楚起见,这种答复应该作为对方的回答(Fommil)而不是作为一个单独的,新的答案作为评论。 –

+0

谢谢。我已经更新了答案,按照我理解的流程进行了操作。答案与fommil相同,但增加了信息 –