Synchronous HTTP call in Scala

2019-07-16 14:41发布

问题:

I need to perform a single synchronous HTTP POST call: create an HTTP Post request with some data, connect to the server, send the request, receive the response, and close the connection. It is important to release all resources used to do this call.

Now I am doing it in Java with Apache Http Client. How can I do it with Scala dispatch library ?

回答1:

Something like this should work (haven't tested it though)

import dispatch._, Defaults._
import scala.concurrent.Future
import scala.concurrent.duration._

def postSync(path: String, params: Map[String, Any] = Map.empty): Either[java.lang.Throwable, String] = {
  val r = url(path).POST << params
  val future = Http(r OK as.String).either
  Await.result(future, 10.seconds)
}

(I'm using https://github.com/dispatch/reboot for this example)

You explicitly wait for the result of the future, which is either a String or an exception.

And use it like

postSync("http://api.example.com/a/resource", Map("param1" -> "foo") match {
  case Right(res) => println(s"Success! Result was $res")
  case Left(e) => println(s"Woops, something went wrong: ${e.getMessage}")
}


回答2:

We all know that Scala's important feature is async. So there are lots of solutions to tell people how to do HTTP CALL ASYNC. For example, dispatch is the async http library. But here we care about how to implement sync http call by scala. I use a trick to do it.

Here is my solution:

val svc = url(#your_url)
val response = Http(svc OK dispatch.as.json4s.Json)
response onComplete {
    // do_what_you_want
}
while(!response.isCompleted) {
    Thread.sleep(1000)
}
// return_what_you_want

So here I use "isCompleted" to help me to wait until finish. So it is a trick to convert async to sync.



标签: scala http