【问题标题】:Problem: "Extracting" JSON using lift-json in an Android (Scala) application问题:在 Android (Scala) 应用程序中使用 lift-json “提取” JSON
【发布时间】:2026-01-24 13:15:01
【问题描述】:

我想使用 lift-json 库反序列化 JSON-String。在我的 Android 应用程序中,我使用的是 Scala 2.9.0 和 lift-json_2.9.0_2.4-M1。

我从 lift-json 自述文件中举了一个简单的例子,但是每次我尝试从 JSON-String 中提取值时,我都会在调用 Activity 时得到一个 net.liftweb.json.MappingException。似乎没有传递到“提取”的参数。

这是我的活动:

import _root_.android.app.Activity
import _root_.android.os.Bundle
import net.liftweb.json._

class JsonTest extends Activity {

  override def onCreate(savedInstanceState: Bundle) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.mainactivity)

    implicit val formats = DefaultFormats
    case class NumList(numbers: List[Int])
    val json = parse(""" { "numbers" : [1, 2, 3, 4] } """)
    json.extract[NumList]
  }
}

我得到的例外是:

06-29 12:09:31.548: ERROR/AndroidRuntime(405): FATAL EXCEPTION: main
    java.lang.RuntimeException: Unable to start activity ComponentInfo{de.fhs.spirit/de.fhs.spirit.JsonTest}: net.liftweb.json.MappingException: Parsed JSON values do not match with class constructor
    args=
    arg types=
    constructor=public de.fhs.spirit.JsonTest$NumList$2(de.fhs.spirit.JsonTest,scala.collection.immutable.List)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
    at android.app.ActivityThread.access$2300(ActivityThread.java:125)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:123)
    at android.app.ActivityThread.main(ActivityThread.java:4627)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:521)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
    at dalvik.system.NativeStart.main(Native Method)
    Caused by: net.liftweb.json.MappingException: Parsed JSON values do not match with class constructor
    args=
    arg types=
    constructor=public de.fhs.spirit.JsonTest$NumList$2(de.fhs.spirit.JsonTest,scala.collection.immutable.List)
    at net.liftweb.json.Meta$.fail(Meta.scala:185)
    at net.liftweb.json.Extraction$.instantiate$1(Extraction.scala:257)
    at net.liftweb.json.Extraction$.newInstance$1(Extraction.scala:280)
    at net.liftweb.json.Extraction$.build$1(Extraction.scala:298)
    at net.liftweb.json.Extraction$.extract0(Extraction.scala:345)
    at net.liftweb.json.Extraction$.net$liftweb$json$Extraction$$extract0(Extraction.scala:194)
    at net.liftweb.json.Extraction$.extract(Extraction.scala:42)
    at net.liftweb.json.JsonAST$JValue.extract(JsonAST.scala:290)
    at de.fhs.spirit.JsonTest.onCreate(JsonTest.scala:16)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
    ... 11 more

如果您知道如何解决我的问题,那就太好了。 谢谢!

您好, 伊拉兹

【问题讨论】:

    标签: android json scala lift


    【解决方案1】:

    我怀疑 Lift 在这种模式下使用反射。它可能在 Android 中根本不起作用,或者可能需要删除一些已删除的内容not。我建议您尝试使用其他一些替代方法。

    另见this question——我的怀疑来自于它在 REPL 上不起作用的评论。并不是说 REPL 没有反射,而是它的包结构可能会让 Lift 库感到困惑。

    【讨论】:

    • 感谢您的回答。我现在正在使用谷歌 Gson。不幸的是,它不是 Scala,但它可以工作。
    • 你能用 GSon 反序列化 Scala 对象,还是根本不使用 Scala?
    • 如果你使用 Gson,例如你的 Json-String 中有一个 List,Gson 返回一个 java.util.List。如果您想改用 scala.List,则必须使用“import scala.collection.JavaConversions._”和“javaList.toList”转换此列表。这就是你的意思吗,乔普莫?