2017-12-06 4 views
0

json応答を受け取り、それをケースクラスに変換するためにsttp json4sライブラリと一緒にsttpコアライブラリを使用しようとしています。ケースクラスの値にアクセスできない

のGithub上のソースコードは、hereと私は複製しようとしています。この例のドキュメントであるURL http://httpbin.org/get?foo=barからGET要求に対する応答がどのように見えるhere

です:

{ 
    "args": { 
    "foo": "bar" 
    }, 
    "headers": { 
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", 
    "Accept-Encoding": "gzip,deflate", 
    "Accept-Language": "en-GB,en-US;q=0.9,en;q=0.8", 
    "Connection": "close", 
    "Cookie": "_gauges_unique_day=1; _gauges_unique_month=1; _gauges_unique_year=1; _gauges_unique=1; stale_after=never", 
    "Forwarded": "for=49.255.235.138", 
    "Host": "httpbin.org", 
    "Save-Data": "on", 
    "Scheme": "http", 
    "Upgrade-Insecure-Requests": "1", 
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36" 
    }, 
    "origin": "49.255.235.138, 66.249.82.79", 
    "url": "http://httpbin.org/get?foo=bar" 
} 

上記のjson応答を読み取ろうとするケースクラスは、次のようになります。

case class HttpBinResponse(
    args: Map[String, String], 
    origin: String, 
    headers: Map[String,String] 
) 

ケースクラスはテストファイルの先頭に定義されており、テストにアクセスできます。

このテストに合格:

it should "send a GET request parse response as JSON" in { 
    implicit val backend = HttpURLConnectionBackend() 
    val queryParams = Map("foo" -> "bar", "bugs" -> "life") 

    val endpoint:Uri = uri"http://httpbin.org/get?foo=bar" 

    val request = sttp 
    .get(endpoint) 
    .response(asJson[HttpBinResponse]) 

    val response = request.send() 
    // response.body is an Either 

    response.code should be(200) 
    val res = response.body.fold(_ => { "Error" }, a => { a }) 

    res shouldBe a[HttpBinResponse] 
} 

エラーを生成したコードは次のようになります。私がしようとするとres.originから値にアクセスするときに、私が見る、しかし

it should "send a GET request parse response as JSON" in { 
    implicit val backend = HttpURLConnectionBackend() 

    val queryParams = Map("foo" -> "bar", "bugs" -> "life") 

    val endpoint:Uri = uri"http://httpbin.org/get?foo=bar" 

    val request = sttp 
    .get(endpoint) 
    .response(asJson[HttpBinResponse]) 

    val response = request.send() 
    // response.body is an Either 

    response.code should be(200) 
    val res = response.body.fold(_ => { "Error" }, a => { a }) 

    res shouldBe a[HttpBinResponse] 
    println(res.origin) 
} 

エラーはvalue origin is not a member of java.io.Serializable

28. Waiting for source changes... (press enter to interrupt) 
[info] Compiling 1 Scala source to /Users/localuser/Do/scalaexercises/target/scala-2.12/test-classes... 
[error] /Users/localuser/Do/scalaexercises/src/test/scala/example/SttpSpec.scala:58: value origin is not a member of java.io.Serializable 
[error]  println(res.origin) 
[error]    ^
[error] one error found 
[error] (test:compileIncremental) Compilation failed 
+0

コードを投稿した場合、エラーが発生します(「原点」という用語は、クラス定義とエラーメッセージ以外にはどこにも見つかりません)。 – Dima

+0

@Dimaこれがより良いかどうか教えてください。私はjsonレスポンスとケースクラスを先頭に含めました。ケースクラスはテストファイルの先頭に定義されています。 – vamsiampolu

+0

'val res'はどのタイプですか? – Dima

答えて

0

質問はRob Norris on the gitter scala channelによって次のように回答されました:

結果がシリアライズ可能です。パターンマッチングを試してみるか、Stringの代わりにsys.errorにフォールドしてください。結果のマッチング

  1. パターン:

    val res = response.body.fold(_ => { "Error" }, a => { a }) 
    res match { 
        case HttpBinResponse(_, origin) => { 
        println("-----------------------------") 
        print("The origin for the request is ") 
        print(origin) 
        println("-----------------------------") 
        } 
        case _ => "Error" 
    } 
    
  2. 代わりに文字列、この場合に必要と一致するパターンでsys.errorに委ね倍:

    val res = response.body.fold(
        _ => { error("Error") }, 
        a => { a } 
    ) 
    println(res.origin) 
    res.args should contain("foo" -> "bar") 
    res.args should contain key("bugs") 
    res.args should contain value("life") 
    res.origin.length should be >10  
    

をこれらの2つのアプローチのいずれかが問題を解決します。

関連する問題