5

外部サーバーからJsonを取得している状況に陥っています(そのサーバーを制御することはできません)。Json には、1 回以上発生する可能性がある 1 つの要素があります。net.liftweb.json 機能を使用して解析しようとしていますが、要素が複数回発生する場合にのみ正常に機能します。要素が 1 回だけ出現する場合、解析に失敗します。

コード例を次に示します。

import net.liftweb.json._
import net.liftweb.json.JsonDSL._

case class JSonListIssue(foo: List[String])

class JSonTest extends TestCase {

  implicit val formats = net.liftweb.json.DefaultFormats; 

  def testJsonList {
    val jsonStr2Foos = "{\"foo\": \"bar\", \"foo\": \"bar2\"}"
    val json = (parse(jsonStr2Foos).extract[JSonListIssue]) 
    assertEquals(2, json.foo.size)

    val jsonStr1Foo = "{\"foo\": \"bar\"}"
    val json2 = (parse(jsonStr1Foo).extract[JSonListIssue]) // Results in Json MappingException
    assertEquals(1, json2.foo.size)
  }

}

上記のコードでは、2 番目の parse ステートメントが失敗します。ケース クラスを次のように定義すると、2 番目の解析は機能しますが、最初の解析は失敗します。

    case class JSonListIssue(foo: String)

これをきれいな方法で解決する方法について何か提案はありますか? もちろん、MappingException をキャッチして、他のケース クラスを使用して解析することもできますが、それは汚いです...

ありがとう、ゲロ

4

1 に答える 1

0

したがって、まず第一に、その API を書いた人を制御することはできませんが、彼らに会ったことがある場合は、このようなばかげたことをしたことで親切に彼らの足を撃ってください。:P

だから、それは世界で最もクリーンな解決策ではありませんが、私はあなたのために働く何かを思いついたと思います. 演算子を使用して JSON を解析することによって生成された JValue を直接クエリすることができます\

したがって、このようなものがうまくいくはずです。

case class JsonListIssue(foo: List[String])

def extractJsonListIssue(json: JValue) = {
  json \ "foo" match {
    case JString(foo) =>
      JsonListIssue(List(foo))

    case _ =>
      json.extract[JsonListIssue]
  }
}

json \ "foo"コンパイルするために括弧が必要な場合とそうでない場合があります。しかし!ほとんどの場合、それでうまくいくと思います。FWIW、本当に Lift-y になりたい場合は、ここで Box を使用することを真剣に検討し、tryo を使用して抽出からの例外を失敗に変えて、呼び出しスタックの上位でキャッチできるようにする必要があります。したがって、それは次のようになります。

// Add these guys to your existing imports
import net.liftweb._
  import common._
  import util.Helpers._

case class JsonListIssue(foo: List[String])

def extractJsonListIssue(json: JValue) = {
  json \ "foo" match {
    case JString(foo) =>
      Full(JsonListIssue(List(foo)))

    case _ =>
      // Will return a Full with the result of the method on
      // success and a Failure if extract throws an exception.
      tryo(json.extract[JsonListIssue])
  }
}

これを、コード内の別の場所で for 内包表記で使用できます。

これが機能しない場合はお知らせください。よりクリーンなものがあればお知らせします。歓声メイト!

于 2012-10-01T03:16:19.687 に答える