Выполнение 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

Я бы не стал предлагать это как лучший вариант, но стоит упомянуть.

Ответ 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)
  }