1

Lift を使用して、JSON を「抽出」(ケース・クラス表現を取得) しようとしています。

val json: JValue = getJson()
case class BigObj(name: String, age: Int, ...)
json.extract[BigObj]

22 個を超える引数を使用すると、ケース クラスが 22 個の引数を超えることはできないという JVM 実行時例外が発生します。

この制限を回避するにはどうすればよいですか?

4

2 に答える 2

2

前述のように、ケース クラスを明示的に使用してその制限を克服することはできませんが、ケース クラスなしで抽出メソッドを使用することはできます。REPL を実行して検証したこの例を参照してください。

scala> import net.liftweb.json._
import net.liftweb.json._

scala> implicit val formats = net.liftweb.json.DefaultFormats
formats: net.liftweb.json.DefaultFormats.type = net.liftweb.json.DefaultFormats$@734784c4

scala> val json = parse(""" {
     |           "v1": "Test1",
     |           "v2": "Test2",
     |           "v3": "Test3",
     |           "v4": "Test4",
     |           "v5": "Test5",
     |           "v6": "Test6",
     |           "v7": "Test7",
     |           "v8": "Test8",
     |           "v9": "Test9",
     |           "v10": "Test10",
     |           "v11": "Test11",
     |           "v12": "Test12",
     |           "v13": "Test13",
     |           "v14": "Test14",
     |           "v15": "Test15",
     |           "v16": "Test16",
     |           "v17": "Test17",
     |           "v18": "Test18",
     |           "v19": "Test19",
     |           "v20": "Test20",
     |           "v21": "Test21",
     |           "v22": "Test22",
     |           "v23": "Test23"
     | } """)
json: net.liftweb.json.JValue = JObject(List(JField(v1,JString(Test1)), JField(v2,JString(Test2)), JField(v3,JString(Test3)), JField(v4,JString(Test4)), JField(v5,JString(Test5)), JField(v6,JString(Test6)), JField(v7,JString(Test7)), JField(v8,JString(Test8)), JField(v9,JString(Test9)), JField(v10,JString(Test10)), JField(v11,JString(Test11)), JField(v12,JString(Test12)), JField(v13,JString(Test13)), JField(v14,JString(Test14)), JField(v15,JString(Test15)), JField(v16,JString(Test16)), JField(v17,JString(Test17)), JField(v18,JString(Test18)), JField(v19,JString(Test19)), JField(v20,JString(Test20)), JField(v21,JString(Test21)), JField(v22,JString(Test22)), JField(v23,JString(Test23))))

scala> class MyLargeArgClass(val v1:String, val v2:String, val v3:String, val v4:String, val v5:String, val v6:String, val v7:String, val v8:String, val v9:String, val v10:String, val v11:String, val v12:String, val v13:String, val v14:String, val v15:String, val v16:String, val v17:String, val v18:String, val v19:String, val v20:String, val v21:String, val v22:String, val v23:String) {
     | 
     |   override def toString = "MyLargeArgClass(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)".format(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23)
     | 
     | }
defined class MyLargeArgClass

scala> json.extract[MyLargeArgClass]
res0: MyLargeArgClass = MyLargeArgClass(Test1, Test2, Test3, Test4, Test5, Test6, Test7, Test8, Test9, Test10, Test11, Test12, Test13, Test14, Test15, Test16, Test17, Test18, Test19, Test20, Test21, Test22, Test23)

そして、クラスから JSON に戻ります

scala> Extraction.decompose(res0)
res1: net.liftweb.json.JValue = JObject(List(JField(v1,JString(Test1)), JField(v2,JString(Test2)), JField(v3,JString(Test3)), JField(v4,JString(Test4)), JField(v5,JString(Test5)), JField(v6,JString(Test6)), JField(v7,JString(Test7)), JField(v8,JString(Test8)), JField(v9,JString(Test9)), JField(v10,JString(Test10)), JField(v11,JString(Test11)), JField(v12,JString(Test12)), JField(v13,JString(Test13)), JField(v14,JString(Test14)), JField(v15,JString(Test15)), JField(v16,JString(Test16)), JField(v17,JString(Test17)), JField(v18,JString(Test18)), JField(v19,JString(Test19)), JField(v20,JString(Test20)), JField(v21,JString(Test21)), JField(v22,JString(Test22)), JField(v23,JString(Test23))))

をオーバーライドするtoString必要はありませんでした。追加されているデータを確認する必要がありました。ただし、これは ではないためcase class、付属の自動メソッドの一部が失われます。したがって、HTTP セッションに配置する必要がある場合は、実装することをお勧めしますSerializable。パターンマッチングの場合、unapplyメソッドなどが必要になります...

formatsを使用して、JSON からデータを解析および抽出するための独自の追加ルールを指定することもできます。

于 2013-09-18T19:39:24.447 に答える