2

我想要 result.entity.asString 的内容,但结果是空的。而且我有很多警告让不停。我的代码是:`

implicit  val system: ActorSystem = ActorSystem("simple-spray-client")
val log: LoggingAdapter = Logging(system, getClass)
val pipeline: SendReceive = sendReceive
val responseFuture: Future[HttpResponse] = pipeline {
Get("https://api.guildwars2.com/v2/items")
}
val re = responseFuture.onComplete {
case Success(result: HttpResponse) => {
  result.entity.asString
  shutdown()
 }
 case Failure(error) =>
  log.error(error, "Couldn't get list of items")
  shutdown()
}


def shutdown(): Unit = {
 IO(Http).ask(Http.CloseAll)(1.second).await
 system.shutdown()
}}

` 结果是:

()
[WARN] [10/27/2015 11:26:04.776] [simple-spray-client-akka.actor.default-dispatcher-4] [akka://simple-spray-client/user/IO-HTTP/group-0/0] Illegal  response header: Illegal 'Cache-Control' header: Invalid input '"', expected  $timesCache$minusControl (line 1, pos 1):
"public, max-age=300"
 ^
 [WARN] [10/27/2015 11:26:04.779] [simple-spray-client-akka.actor.default- dispatcher-4] [akka://simple-spray-client/user/IO-HTTP/group-0/0] Illegal response header: Illegal 'Access-Control-Expose-Headers' header: Invalid input '"', expected  $timesAccess$minusControl$minusExpose$minusHeaders (line 1, pos 1):
 "X-Result-Total, X-Result-Count"
  ^
4

4 回答 4

0

我跟踪您共享的日志消息get并向 api url 发出请求。这里是响应头;

你可以看到它Cache-Control并有日志消息指示Access-Control-Expose-Headers的双引号。".."

我认为您应该首先检查http status code哪些有助于查看主要问题。

在此处输入图像描述

于 2015-10-27T11:56:03.643 回答
0

开始一些代码清理和格式化怎么样?:) (responseFuture.toString??println(re))。这肯定有助于吸引答案。

据说该请求是由喷雾触发的。警告与响应中的标题有关。我运行了查询,响应标头是:

Cache-Control: "public, max-age=300" 
Transfer-Encoding: chunked 
Content-Type: application/json; charset=utf-8 
Content-Encoding: gzip 
Content-Language: en 
Expires: Tue, 27 Oct 2015 11:44:47 +0000 
Vary: Accept-Encoding 
Server: Microsoft-IIS/7.5 
X-Result-Total: 48798
X-Result-Count: 48798
Access-Control-Expose-Headers: "X-Result-Total, X-Result-Count"
Access-Control-Allow-Origin: *
X-Content-Type-Options: nosniff
Date: Tue, 27 Oct 2015 11:39:47 GMT 

正如您可以看到的值,Cache-ControlAccess-Control-Expose-Headers以双引号开头,如喷雾所警告的那样。

现在您可以尝试重新实现为

pipeline {
    Get("https://api.guildwars2.com/v2/items")
}.onComplete {

    case Success(result: HttpResponse) => 
        log.info("Result: "+result.entity.asString)
        shutdown()

    case Failure(error) =>
        log.error(error, "Couldn't get list of items")
        shutdown()
}

...并查看控制台上的信息级别记录的内容(不确定您使用的是什么日志框架)

此外,在访问实体之前检查 HTTP 响应代码可能是个好主意

于 2015-10-27T11:53:57.040 回答
0

据我了解,您想要:

import scala.concurrent.Await
import scala.concurrent.duration._
        def extract(responseFuture: Future[HttpResponse]): HttpResponse = Await.result(responseFuture, xx.seconds)

val myOlolo = extract(responseFuture).entity.asString
于 2016-03-10T15:23:58.593 回答
-1

您可以按照其他答案中的建议拥有onSuccess和lambdas 并将其传递给您想要的课程,这似乎是您关心的问题。onFailuresuccess value

class ItemServer {

    def callServer() : Unit = {
      val pipeline: HttpRequest => Future[HttpResponse] = sendReceive
      val response: Future[HttpResponse] = pipeline(Get("https://api.guildwars2.com/v2/items"))

      response.onComplete {
        case Success(response : HttpResponse) => new SomeService().doSomething(response.entity.asString)
        case Failure(error) => new SomeService().doSomethingElse(error.getMessage)
      }
    }

}

class SomeService {
  def doSomething(bodyString: String): Unit = {
    val cleanupResponse  = bodyString.replaceAll("\n", "")
    val bodyAsList = cleanupResponse.substring(1, cleanupResponse.length).split(",").toList
    println(bodyAsList)
  }

  def doSomethingElse(bodyString: String): Unit = {
    println(bodyString)
  }
}

或者,您可以阻止直到收到响应,然后使用响应做任何您想做的事情,如下面的测试所示,

class ItemServerTests extends FunSpec with BeforeAndAfterEach {
   describe("/items") {
    it("responds with success message") {
      val pipeline: HttpRequest => Future[HttpResponse] = sendReceive
      val response: Future[HttpResponse] = pipeline(Get("https://api.guildwars2.com/v2/items"))

      val bodyString = Await.result(response, Duration("10 seconds")).entity.asString.trim
      new SomeService().doSomething(bodyString)
    }
  }
}


class SomeService {
  def doSomething(bodyString: String): Unit = {
    val cleanupResponse = bodyString.replaceAll("\n", "")
    val bodyAsList = cleanupResponse.substring(1, cleanupResponse.length).split(",").toList
    assert(bodyAsList.size == 55372)
  }
}
于 2017-01-09T01:47:17.177 回答