简体   繁体   English

为列表中的每个URL发送WS请求,并将响应映射到新列表

[英]Send a WS request for each URL in a list and map the responses to a new list

I'm developing a REST server in Play with Scala, that at some point needs to request data at one or more other web services. 我正在用Scala进行Play开发中的REST服务器,有时需要在一个或多个其他Web服务上请求数据。 Based on the responses from these services the server must compose a unified result to use later on. 根据这些服务的响应,服务器必须组成一个统一的结果,以便以后使用。

Example : 范例

Event C on www.someplace.com needs to be executed. 需要执行www.someplace.com上的事件C。 In order to execute Event C, Event A on www.anotherplace.com and Event B on www.athirdplace.com must also be executed. 为了执行事件C,还必须执行www.athirdplace.com上的事件A和www.anotherplace.com事件B。

Event C has a Seq(www.anotherplace.com, www.athirdplace.com) from which I would like to iterate and send a WS request to each URL respectively to check wether B and C are executed. 事件C有一个Seq(www.anotherplace.com, www.athirdplace.com) ,我想从中进行迭代,并将WS请求分别发送到每个URL,以检查B和C是否已执行。

It is assumed that a GET to these URLs returns either true or false 假定这些URL的GET返回truefalse

How do I collect the responses from each request (preferably combined to a list) and assert that each response is equal to true ? 如何收集每个请求的响应(最好组合到一个列表中)并断言每个响应都等于true

EDIT : An event may contain an arbitrary number of URL's. 编辑 :一个事件可以包含任意数量的URL。 So I cant know beforehand how many WS requests i need to send. 因此,我无法事先知道我需要发送多少个WS请求。

Have a look at the documentation and see if you can get their example to work. 查看文档 ,看看是否可以使他们的示例生效。 Try something like this: 尝试这样的事情:

val futureResponse: Future[WSResponse] = for {
  responseOne <- WS.url(urlOne).get()
  responseTwo <- WS.url(responseOne.body).get()
  responseThree <- WS.url(responseTwo.body).get()
} yield responseOne && responseTwo && responseThree

You probably need to parse the response of your WebService since they (probably) won't return booleans, but you'll get the idea. 您可能需要解析WebService的响应,因为它们(可能)不会返回布尔值,但是您会明白的。

Short Answer 简短答案

You can use sequence method available on Future object. 您可以使用Future对象上可用的sequence方法。

For example: 例如:

import scala.concurrent.Future

val urls = Seq("www.anotherplace.com", "www.athirdplace.com")
val requests = urls.map(WS.url)
val futureResponses = Future.sequence(requests.map(_.get()))

Aggregated Future 汇总Future

Note that the type of futureResponses will be Future[Seq[WSResponse]] . 请注意, futureResponses的类型将为Future[Seq[WSResponse]] Now you can work on the results: 现在您可以处理结果了:

futureResponses.map { responses =>
  responses.map { response =>
    val body = response.body
    // do something with response body
  }
}

More Details 更多细节

From ScalaDocs of sequence method: ScalaDocssequence方法:

Transforms a TraversableOnce[Future[A]] into a Future[TraversableOnce[A]]. 将TraversableOnce [Future [A]]转换为Future [TraversableOnce [A]]。 Useful for reducing many Futures into a single Future. 对于将许多期货简化为单个期货很有用。

Note that if any of the Future s you pass to sequence fails, the resulting Future will be failed as well. 请注意,如果传递给sequence任何Future失败,则生成的Future也将失败。 Only when all Future s are completed successfully the result will complete successfully. 仅当所有Future成功完成时,结果才会成功完成。 This is good for some purposes, especially if you want to send requests at the same time, no one after another. 这对于某些目的是有好处的,特别是如果您想同时发送请求,一个又一个地发送请求,则尤其如此。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM