Выполнение HTTP-запроса в Scala
Я пытаюсь выдать простой запрос POST в webservice, который возвращает некоторый XML в Scala.
Кажется, что Dispatch является стандартной библиотекой, используемой для этой задачи, но я не могу найти документацию для нее. Основной сайт, на который я ссылаюсь выше, подробно объясняет, что является обещанием и как выполнять асинхронное программирование, но фактически не документирует API. Существует периодическая таблица - это выглядит немного страшно - но это только кажется полезным людям, которые уже знают, что делать, и нужно только напоминание для критический синтаксис.
Также кажется, что У Scalaz есть некоторые возможности для HTTP, но я не могу найти для него никакой документации.
Ответы
Ответ 1
Я использую следующее: https://github.com/scalaj/scalaj-http.
Вот простой запрос GET:
import scalaj.http.Http
Http("http://foo.com/search").param("q", "monkeys").asString
и пример POST:
val result = Http("http://example.com/url").postData("""{"id":"12","json":"data"}""")
.header("Content-Type", "application/json")
.header("Charset", "UTF-8")
.option(HttpOptions.readTimeout(10000)).asString
Scalaj HTTP доступен через SBT:
libraryDependencies += "org.scalaj" % "scalaj-http_2.11" % "2.3.0"
Ответ 2
Вы можете использовать spray-client. Документации не хватает (мне потребовалось некоторое копание, чтобы узнать как делать запросы GET с параметрами запроса), но это отличный вариант, если вы уже используете спрей. И документация лучше, чем отправка.
Мы используем его в AI2 над dispatch, поскольку операторы менее символичны, и мы уже используем спрей/актеров.
import spray.client.pipelining._
val url = "http://youruri.com/yo"
val pipeline: HttpRequest => Future[HttpResponse] = sendReceive
// Post with header and parameters
val responseFuture1: Future[String] = pipeline(Post(Uri(url) withParams ("param" -> paramValue), yourPostData) map (_.entity.asString)
// Post with header
val responseFuture2: Future[String] = pipeline(Post(url, yourPostData)) map (_.entity.asString)
Ответ 3
Я использую отправку: http://dispatch.databinder.net/Dispatch.html
Они только что выпустили новую версию (0.9.0) с полным новым api, который мне очень нравится. И это асинхронно.
Пример из страницы проекта:
import dispatch._
val svc = url("http://api.hostip.info/country.php")
val country = Http(svc OK as.String)
for (c <- country)
println(c)
edit: Это может помочь вам https://github.com/dispatch/reboot/blob/master/core/src/main/scala/requests.scala
Ответ 4
Другим вариантом является playafe-plays, который представляет собой библиотеку WS Framework Framework, выложенную как автономную библиотеку lib:
http://blog.devalias.net/post/89810672067/play-framework-seperated-ws-library
Я бы не стал предлагать это как лучший вариант, но стоит упомянуть.
Ответ 5
Почему бы не использовать Apache HttpComponents? Здесь часто задаваемые вопросы по приложениям, которые охватывают широкий спектр сценариев.
Ответ 6
Если я могу сделать бесстыдный плагин, у меня есть API под названием Bee-Client, который является просто оболочкой в Scala для Java HttpUrlConnection.
Ответ 7
Мне пришлось сделать то же самое, чтобы протестировать одну конечную точку (в тесте Integration). Итак, следующий код для получения ответа от запроса GET в Scala.
Я использую Scala.io.Source для чтения с конечной точки и ObjectMapper для преобразования json в объект.
private def buildStockMasterUrl(url:String, stockStatus:Option[String]) = {
stockStatus match {
case Some(stockStatus) => s"$url?stockStatus=${stockStatus}"
case _ => url
}
}
private def fetchBooksMasterData(stockStatus:Option[String]): util.ArrayList[BooksMasterData] = {
val url: String = buildBooksMasterUrl("http://localhost:8090/books/rest/catalogue/booksMasterData",stockStatus)
val booksMasterJson : String = scala.io.Source.fromURL(url).mkString
val mapper = new ObjectMapper()
apper.readValue(booksMasterJson,classOf[util.ArrayList[BooksMasterData]])
}
case class BooksMasterData(id:String,description: String,category: String)
И вот мой метод тестирования для того же
test("validate booksMasterData resource") {
val booksMasterData = fetchBooksMasterData(Option(null))
booksMasterData.size should be (740)
}