使用 Maven 时如何在 Play 框架项目中注入 WSClient?

Jac*_*Jac 1 scala maven playframework ws-client

当创建 Play 框架项目并用于WSClient进行 REST 调用时,官方 Play 框架文档建议添加wsbuild.sbt管理依赖项。如果使用 Maven,则 ws 依赖项包含在:

<dependency>
  <groupId>com.typesafe.play</groupId>
  <artifactId>play-ws_2.12</artifactId>
  <version>${play2.version}</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

但是,当尝试使用如下所示的片段调用 Web 服务时:

@Singleton
class Controller @Inject()(
  ws: WSClient,
  controllerComponents: ControllerComponents
)(implicit ec: ExecutionContext)
  extends AbstractController(controllerComponents) {
  def callApi(): Action[AnyContent] = Action.async { _ =>
    ws
      .url("https://mywebservice.com/api/bla")
      .get()
      .map(response => Ok(response.body.toString))
  }
}
Run Code Online (Sandbox Code Playgroud)

然后出现如下错误:

CreationException: Unable to create injector, see the following errors:

1) No implementation for play.api.libs.ws.WSClient was bound.
  while locating play.api.libs.ws.WSClient
    for the 1st parameter of controllers.MyController.<init>(MyController.scala:13)
  while locating controllers.MyController
    for the 3rd parameter of router.Routes.<init>(Routes.scala:33)
  at play.api.inject.RoutesProvider$.bindingsFromConfiguration(BuiltinModule.scala:123):
Binding(class router.Routes to self) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$4)
Run Code Online (Sandbox Code Playgroud)

Jac*_*Jac 5

正如文档所说:

\n\n
\n

注意:在 Play 2.6 中,Play WS 已分为两部分,一个是不依赖于 Play 的底层独立客户端,另一个是顶部使用 Play 特定类的包装器。此外,Play WS 中现在使用 AsyncHttpClient 和 Netty 的阴影版本来最大程度地减少库冲突,主要是为了让 Playxe2x80x99s HTTP 引擎可以使用不同版本的 Netty。请参阅 2.6 迁移指南以了解更多信息。

\n
\n\n

查看 2.6 迁移指南我们可以看到:

\n\n
\n

如果您有 Play SBT 项目,您仍然可以通过将以下行添加到 build.sbt 来添加 WS:

\n
\n\n
libraryDependencies += ws\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n

这包括 play-ahc-ws 模块 [...]

\n
\n\n

因此,为了解决这个问题,我们必须将play-ahc-ws模块添加到 Maven 的 pom.xml 中:

\n\n
libraryDependencies += ws\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果像代码示例中那样使用 Guice,依赖注入将由 Guice 处理。

\n