Liftweb 在 Object 中有效,但在 Class 中无效

Liftweb works in Object but not in Class

此代码有效:

import net.liftweb.json.{DefaultFormats, parse}

object JsonTest {
  def main(args: Array[String]): Unit = {
    implicit val formats = DefaultFormats // Brings in default date formats etc.
    case class RawObject(filters: List[ChunkObject])
    case class ChunkObject(name: String)

    val json = parse("""{"filters": []}""").extract[RawObject]
    println(json)
  }
}

它打印:

RawObject(List())

class 中的相同代码不会:

import net.liftweb.json.{DefaultFormats, parse}

class JsonTest2 {
  def fct(): Unit = {
    implicit val formats = DefaultFormats // Brings in default date formats etc.
    case class RawObject(filters: List[ChunkObject])
    case class ChunkObject(name: String)

    val json = parse("""{"filters": []}""").extract[RawObject]
    println(json)
  }
}

object JsonTest2 {
  def main(args: Array[String]): Unit = {
    val jt = new JsonTest2
    jt.fct()
  }
}

错误:

Exception in thread "main" net.liftweb.json.MappingException: Parsed JSON values do not match with class constructor
args=List()
arg types=scala.collection.immutable.Nil$
constructor=public JsonTest2$RawObject(JsonTest2,scala.collection.immutable.List)
    at net.liftweb.json.Meta$.fail(Meta.scala:227)
    at net.liftweb.json.Extraction$.instantiate(Extraction.scala:274)
    at net.liftweb.json.Extraction$.newInstance(Extraction.scala:308)
    at net.liftweb.json.Extraction$.build(Extraction.scala:379)
    at net.liftweb.json.Extraction$.extract0(Extraction.scala:444)
    at net.liftweb.json.Extraction$.extract0(Extraction.scala:206)
    at net.liftweb.json.Extraction$.extract(Extraction.scala:43)
    at net.liftweb.json.JsonAST$JValue.extract(JsonAST.scala:703)
    at JsonTest2.fct(JsonTest2.scala:9)
    at JsonTest2$.main(JsonTest2.scala:17)
    at JsonTest2.main(JsonTest2.scala)
Caused by: java.lang.IllegalArgumentException: wrong number of arguments
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at net.liftweb.json.Extraction$.instantiate(Extraction.scala:265)
    ... 9 more

我错过了什么?

PS:使用简单的 json(只有一个带有字符串值的字段,因此内部没有列表)它在对象和 Class

中都有效

编辑:我认为这与函数内的 case class 定义有关,但我不明白为什么。

从错误消息来看,RawObject 的构造函数似乎采用了 liftweb 不期望的附加参数:

constructor=public JsonTest2$RawObject(JsonTest2,scala.collection.immutable.List)

RawObject 是嵌套类型,在 Scala 中,嵌套类型对于包含对象的每个实例都是唯一的。因此 JsonTest2 的一个实例中的 RawObjectJsonTest2.

的另一个实例中的 RawObject 的类型不同

我猜测 Scala 将包含类型 (JsonTest2) 的实例放在嵌套类型 (RawObject) 中,以便它可以在运行时确定类型。因此 RawObject.

的构造函数的 JsonTest2 参数

因此将 RawObjectChunkObject 移出 JsonTest2 class 将解决问题。这些可以放在伴随对象中以保持整洁。