I have this simple test Scala application, which a blocking http request:
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
}
}
This application fails with:
Exception in thread "main" java.lang.RuntimeException: There is no started application
How to solve this issue?
EDIT for 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")
}
}
}
Please see:
for more detailed examples of standalone WSClient usage. If you are migrating from earlier versions, see https://www.playframework.com/documentation/2.5.x/Migration25#Play-WS-upgrades-to-AsyncHttpClient-2
For Play 2.4:
Do not use raw AsyncHttpClientConfig.Builder for HTTPS -- it does not configure a secure SSLContext with hostname validation.
You can create a new WSClient instance using the following code:
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())
Please note that this will start up threads which will not be closed until you close the client:
wsClient.underlying[NingWSClient].close()
and you may run into memory leaks if you don't close it.
Play 2.4 makes it very easy to utilize WS in a standalone app.
The following gist provides a nice working example and the following blog post provides a nice explanation.
Here are the highlights.
Configure build.sbt
libraryDependencies ++= Seq(
"com.typesafe.play" %% "play-ws" % "2.4.0-M2"
)
Initialize the WS client
val config = new NingAsyncHttpClientConfigBuilder(DefaultWSClientConfig()).build
val builder = new AsyncHttpClientConfig.Builder(config)
val client = new NingWSClient(builder.build)
Use WS
client.url("http://www.example.com").get
Release WS resources
client.close()
A started PlayApplication contains a client instance, which WS.client simply points to it. Since you won't start a Play application, You have to create your own client, like this:
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()
Have a look on my project for a similar usecase, I am using play-ws and play-json, without Play itself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With