0

ScalaとArgonautでjsonを解析しようとしています。

反対側の REST サービスから JSON 応答を取得し、その応答での json のフィールドの順序とフィールドの数がわからないとします。たとえば、http: //headers.jsontest.com/ は 5 つのフィールドを含む JSON を返しますが、1 つのフィールドのみを抽出し、他のフィールドを削除したいと考えています。

{
   "Accept-Language": "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3",
   "Host": "headers.jsontest.com",
   "Referer": "http://www.jsontest.com/",
   "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0 Iceweasel/31.4.0",
   "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
}

だから私はいくつかのコードを書いています:

object Service {

  case class Address(headers: String, rest: Option[String])

  implicit def AddressCodecJson: CodecJson[Address] =
    casecodec2(Address.apply, Address.unapply)("headers", "rest")

  def parse(data: String): Option[Address] = {
    Parse.decodeOption[Address](data)
  }

  def main(args: Array[String]): Unit = {
    val src = url("http://headers.jsontest.com/")
    val response: Future[String] = Http(src OK as.String)

    response onComplete {
      case Success(content) => {
        val userData: Option[Address] = parse(content)
        println(s"Extracted IP address = ${userData.get.headers}")
      }
      case Failure(err) => {
        println(s"Error: ${err.getMessage}")
      }
    }
  }
}

しかし、おそらく jsontest からの回答がAddressケースクラスと比較されないため、このコードは機能しません。

次のエラー メッセージが表示されます。

java.util.NoSuchElementException: None.get
    at scala.None$.get(Option.scala:313)
    at scala.None$.get(Option.scala:311)
    at micro.api.Service$$anonfun$main$1.apply(Service.scala:26)
    at micro.api.Service$$anonfun$main$1.apply(Service.scala:23)
    at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32)
    at scala.concurrent.impl.ExecutionContextImpl$$anon$3.exec(ExecutionContextImpl.scala:107)
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.pollAndExecAll(ForkJoinPool.java:1253)
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1346)
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)

名前で指定された 1 つのフィールドのみを取得するにはどうすればよいですか?

4

1 に答える 1

1

コードには次のものがあります。

implicit def AddressCodecJson: CodecJson[Address] =
  casecodec2(Address.apply, Address.unapply)("headers", "rest")

そしてあなたは言った:

私はこの行を置き換えます:val userData: Option[Address] = parse(content) println(s"Extracted IP address = ${userData.get.headers}")println(content)get:{ "Host": "headers.jsontest.com", "User-Agent": "Dispatch/0.11.1-SNAPSHOT", "Accept": "/" }

あなたが持っている応答は次のとおりです。

{ "Host": "headers.jsontest.com", "User-Agent": "Dispatch/0.11.1-SNAPSHOT", "Accept": "/" }

そして、あなたはそれを次のようにデコードしています:

Parse.decodeOption[UserData](data).get

...つまり、確実に、そして明らかにNone.

— さて、期待されるand属性Noneを含まない JSON ディクショナリから非値を取得することを期待するのはなぜですか?headersrest

(値を保持する.getを呼び出すと例外がスローされることはご存じだと思います。)Option[T]None

PS 私は、アドレスが HTTP ヘッダーと何の関係があるのか​​ わかりません...? モデリングの観点から言うと....

于 2015-01-29T16:07:29.610 に答える