2015-01-29 3 views
0

저는 Scala와 Argonaut로 json을 구문 분석하려고합니다.Scala와 Argonaut로 특정 JSON 필드를 추출하십시오.

다른 쪽 REST 서비스에서 JSON 응답을 받았는데 해당 응답 및 필드 수에서 json의 필드 순서를 알지 못한다고 가정합니다. 예를 들어, http://headers.jsontest.com/ 5 개 개의 필드와 JSON을 반환하지만 나는 단지 하나 개의 필드를 추출하고 다른 사람을 드롭 할 :

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}") 
     } 
    } 
    } 
} 

그러나 물론이 코드는 아무튼 :

{ 
    "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" 
} 

그래서 내가 코드를 작성 해요 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) 

:

이 오류 메시지가?

+0

'내용'안에 무엇이 있는지 알려주세요. –

+0

다음 줄을 다음과 같이 바꿉니다. val userData : Option [Address] = parse (content) println (content ")으로 getl : { "println ("추출 IP 주소 = $ {userData.get.headers} "*"*/* " "사용자 에이전트 ":" –

답변

1

코드는 있습니다

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

당신은 말했다 :이 라인 교체

: println(content)val userData: Option[Address] = parse(content) println(s"Extracted IP address = ${userData.get.headers}")를 얻을 : { "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을 다시 받고있어 의미한다.

- 이제 headersrest 속성이 포함되지 않은 JSON 사전에서 None 값을 얻지 못할 것으로 예상되는 이유는 무엇입니까?

(난 당신이 None 값을 유지하는 Option[T].get를 호출하면 예외가 발생 것을 알고 추정하고있다.)

P.S.을 HTTP 헤더와 관련된 주소가 무엇인지 잘 모르겠습니다 ...? 모델링의 관점에서 말하면됩니다.

관련 문제