5

我想在 Play 应用程序之外创建一个 Play Web 服务客户端。对于 Play WS 版本 2.4.x 很容易发现它是这样完成的:

val config = new NingAsyncHttpClientConfigBuilder().build()
val builder = new AsyncHttpClientConfig.Builder(config)
val client = new NingWSClient(builder.build)

但是在 2.5.x 中,NingWSClient现在已弃用 - 而AhcWSClient应该使用 。

不幸的是,我没有找到一个完整的示例来解释在 Play 之外创建和使用 AhcWsClient。目前我这样做:

import play.api.libs.ws.ahc.AhcWSClient
import akka.stream.ActorMaterializer
import akka.actor.ActorSystem

implicit val system = ActorSystem()
implicit val materializer = ActorMaterializer()
val ws = AhcWSClient()

val req = ws.url("http://example.com").get().map{
  resp => resp.body
}(system.dispatcher)

这是创建一个的正确方法AhcWsClient吗?有没有办法创建一个AhcWSClient没有的ActorSystem

4

2 回答 2

5

您可能正在使用编译时依赖注入,否则您只会使用@Inject() (ws: WSClient),对吗?
文档中有一个示例:https
://www.playframework.com/documentation/2.5.x/ScalaWS#using-wsclient 所以你可以在你的应用程序加载器中写这样的东西:

lazy val ws = {
  import com.typesafe.config.ConfigFactory
  import play.api._
  import play.api.libs.ws._
  import play.api.libs.ws.ahc.{AhcWSClient, AhcWSClientConfig}
  import play.api.libs.ws.ahc.AhcConfigBuilder
  import org.asynchttpclient.AsyncHttpClientConfig

  val configuration = Configuration.reference ++ Configuration(ConfigFactory.parseString(
    """
      |ws.followRedirects = true
    """.stripMargin))

  val parser = new WSConfigParser(configuration, environment)
  val config = new AhcWSClientConfig(wsClientConfig = parser.parse())
  val builder = new AhcConfigBuilder(config)
  val logging = new AsyncHttpClientConfig.AdditionalChannelInitializer() {
    override def initChannel(channel: io.netty.channel.Channel): Unit = {
      channel.pipeline.addFirst("log", new io.netty.handler.logging.LoggingHandler("debug"))
    }
  }
  val ahcBuilder = builder.configure()
  ahcBuilder.setHttpAdditionalChannelInitializer(logging)
  val ahcConfig = ahcBuilder.build()
  new AhcWSClient(ahcConfig)
}
applicationLifecycle.addStopHook(() => Future.successful(ws.close))

然后注入ws你的控制器。我不能 100% 确定这种方法,如果一些 Play 大师可以验证这一点,我会很高兴。
关于一个ActorSystem,你只需要它来获得一个线程池来解决它Future。您也可以只导入或注入默认执行上下文:
play.api.libs.concurrent.Execution.Implicits.defaultContext.
或者您可以使用自己的:
implicit val wsContext: ExecutionContext = actorSystem.dispatchers.lookup("contexts.your-special-ws-config").

于 2016-05-11T13:11:19.913 回答
2

AFAIK 这是创建AhcWSClient- 至少在 2.5.0 和 2.5.1 中 - 如Scala API中所见的正确方法

当然,你可以总是使用另一个 HTTP 客户端——Scala 有很多可用的客户端——比如NewmanSpray 客户端等(虽然 Spray 也基于 Akka,所以你也必须创建一个 Actor 系统)

于 2016-04-12T09:11:21.153 回答