如何使用使用playframework库的Scala独立应用程序

时间:2014-10-06 16:14:50

标签: scala playframework-2.0

我有这个简单的测试Scala应用程序,它阻止了http请求:

build.sbt

name := "hello"

version := "1.0"

scalaVersion := "2.11.2"

libraryDependencies += "com.typesafe.play" %% "play-ws" % "2.4.0-M1"

Test.scala

import play.api.libs.json._
import play.api.libs.ws._
import scala.concurrent.duration.Duration
import scala.concurrent.{Await, Future}

object Test {
  def main(args: Array[String]) = {
    val wsClient = WS.client
    val body = getBody(wsClient.url("http://example.com/").get())
    println(s"body: $body")
  }

  def getBody(future: Future[WSResponse]) = {
    val response = Await.result(future, Duration.Inf);
    if (response.status != 200)
      throw new Exception(response.statusText);
    response.body
  }
}

此应用程序失败并显示:

Exception in thread "main" java.lang.RuntimeException: There is no started application

如何解决这个问题?

3 个答案:

答案 0 :(得分:13)

编辑Play 2.5:

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

import scala.concurrent.Future

object Main {
  import scala.concurrent.ExecutionContext.Implicits._

  def main(args: Array[String]): Unit = {
    implicit val system = ActorSystem()
    implicit val materializer = ActorMaterializer()
    val wsClient = AhcWSClient()

    call(wsClient)
      .andThen { case _ => wsClient.close() }
      .andThen { case _ => system.terminate() }
  }

  def call(wsClient: WSClient): Future[Unit] = {
    wsClient.url("http://www.google.com").get().map { response =>
      val statusText: String = response.statusText
      println(s"Got a response $statusText")
    }
  }
}

请参阅:

有关独立WSClient使用的更详细示例。如果您要从早期版本迁移,请参阅https://www.playframework.com/documentation/2.5.x/Migration25#Play-WS-upgrades-to-AsyncHttpClient-2

对于Play 2.4:

不要对HTTPS使用原始AsyncHttpClientConfig.Builder - 它不会使用主机名验证配置安全SSLContext。

您可以使用以下代码创建新的WSClient实例:

import play.api.libs.ws.ning._
import play.api.libs.ws._

val config = new NingAsyncHttpClientConfigBuilder(DefaultWSClientConfig()).build()
val builder = new AsyncHttpClientConfig.Builder(config)
val wsClient:WSClient = new NingWSClient(builder.build())

请注意,这将启动在关闭客户端之前不会关闭的线程:

wsClient.underlying[NingWSClient].close()

如果你不关闭它,你可能会遇到内存泄漏。

答案 1 :(得分:8)

Play 2.4使得在独立应用程序中使用WS非常容易。

以下gist提供了一个很好的工作示例,以下blog post提供了一个很好的解释。

以下是重点。

配置build.sbt

libraryDependencies ++= Seq(
  "com.typesafe.play" %% "play-ws" % "2.4.0-M2"
)

初始化WS客户端

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

使用WS

client.url("http://www.example.com").get

发布WS资源

client.close()

答案 2 :(得分:4)

启动的PlayApplication包含一个客户端实例which WS.client simply points to it。由于您不会启动Play应用程序,因此您必须创建自己的客户端,如下所示:

val client = {
  val builder = new com.ning.http.client.AsyncHttpClientConfig.Builder()
  new play.api.libs.ws.ning.NingWSClient(builder.build())
}
client.url("http://example.com/").get()

my project上查看类似的用例,我使用的是play-ws和play-json,没有Play本身。