2014-10-06 81 views
9

我有这种简单的测试Scala的应用Scala的独立应用程序,其中的阻挡http请求:如何有使用playframework库

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 
    } 
} 

此应用程序失败: 线程“main”中的异常java.lang.RuntimeException:没有启动的应用程序

如何解决这个问题?

回答

13

编辑播放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

对于播放2.4:

不要使用原始AsyncHttpClientConfig.Builder用于HTTPS - 它没有配置与主机验证安全的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() 

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

+0

如何做到这一点最明显的例子是我见过,谢谢Will。 – 2015-02-23 17:01:50

+0

全部现已在2.5.x版中弃用。 – ses 2016-09-20 01:26:22

+0

您好@ses - 请参阅https://www.playframework.com/documentation/2.5.x/ScalaWS#using-wsclient和https://www.playframework.com/documentation/2.5.x/ScalaTestingWebServiceClients – 2016-09-20 01:41:59

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一个类似的用例一看,我用的播放WS和玩游戏JSON,无玩自己。

8

播放2.4使得它很容易利用WS在一个独立的应用程序。

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

以下是亮点。

配置构建。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() 
相关问题