2

I want to have the content of result.entity.asString but the result is empty. And I have many WARNING that make non stop. My Code is: `

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

` the result is:

()
[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"
  ^
timo 123
  • 21
  • 1
  • 3

4 Answers4

0

How about some code clean-up and formatting to start with ? :) (responseFuture.toString? println(re) ?). This would certainly help attracting answers.

This being said the request is being triggered by spray. The warnings are about headers in the response. I ran the query and the response headers are:

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 

As you can see the values for Cache-Control and Access-Control-Expose-Headers start with a double quote, as warned by spray.

Now can you try re-implementing as

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

...and see what is logged at the info level on your console (not sure what logging framework you are using)

Also, checking HTTP response codes before accessing the entity may be a good idea

Bruno Grieder
  • 28,128
  • 8
  • 69
  • 101
  • I want to use the result "result.entity.asString" in other class so I need the value and not display the result. – timo 123 Oct 27 '15 at 13:05
0

I trace log messages you shared and make a get request to api url. Here It's response headers;

You can see that Cache-Control and Access-Control-Expose-Headers have double quote ".." which log message indicate.

I think you should first check http status code which helps to see main problem.

enter image description here

Fatih Donmez
  • 4,319
  • 3
  • 33
  • 45
0

as I understood you want:

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

and

val myOlolo = extract(responseFuture).entity.asString
-1

Either you can have onSuccess and onFailure lambads as suggested in other answers and pass the success value to the class you want, which seems to be your concern.

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

Or, you can block until the response is received and then use the response to do whatever you want, as shown in test below,

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)
  }
}
prayagupa
  • 30,204
  • 14
  • 155
  • 192