2014-10-06 86 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()