【问题标题】:how can have the body of http response spray scala怎么会有http响应体喷scala
【发布时间】:2015-10-27 10:36:05
【问题描述】:

我想要 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"
  ^

【问题讨论】:

    标签: scala spray-client


    【解决方案1】:

    开始一些代码清理和格式化怎么样? :) (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 的值以双引号开头,正如 spray 所警告的那样。

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

    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 响应代码可能是个好主意

    【讨论】:

    • 我想在其他类中使用结果“result.entity.asString”,所以我需要该值而不显示结果。
    【解决方案2】:

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

    您可以看到Cache-ControlAccess-Control-Expose-Headers 有双引号"..",日志消息表明。

    我认为您应该先检查http status code,这有助于了解主要问题。

    【讨论】:

      【解决方案3】:

      据我了解,您想要:

      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
      

      【讨论】:

        【解决方案4】:

        您可以按照其他答案中的建议使用onSuccessonFailure 兰巴德,并将success 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)
          }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-07-13
          • 1970-01-01
          • 2014-09-19
          • 2022-01-05
          • 1970-01-01
          • 2011-04-15
          • 1970-01-01
          • 2017-05-05
          相关资源
          最近更新 更多