在 Scala 中执行 HTTP 请求

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11719373/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 04:23:55  来源:igfitidea点击:

Doing HTTP request in Scala

httpscalascalaz

提问by Andrea

I am trying to issue a simple POST request to a webservice which returns some XML in Scala.

我正在尝试向 Web 服务发出一个简单的 POST 请求,该请求在 Scala 中返回一些 XML。

It seems that Dispatchis the standard library used for this task, but I cannot find documentation for it. The main site, which I link above, explains at length what is a promise and how to do asynchronous programming, but does not actually document the API. There is a periodic table- which looks a bit scary - but it only seems useful to people who already know what to do and only need a reminder for the cryptic syntax.

Dispatch似乎是用于此任务的标准库,但我找不到它的文档。我在上面链接的主站点详细解释了什么是承诺以及如何进行异步编程,但实际上并未记录 API。有一个元素周期表- 看起来有点吓人 - 但它似乎只对那些已经知道该做什么并且只需要提醒神秘语法的人有用。

It also seems that Scalaz has some facility for HTTP, but I cannot find any documentation for it either.

Scalaz似乎也有一些 HTTP 功能,但我也找不到任何相关文档。

回答by kulikov

I use the following: https://github.com/scalaj/scalaj-http.

我使用以下内容:https: //github.com/scalaj/scalaj-http

Here's a simple GET request:

这是一个简单的 GET 请求:

import scalaj.http.{Http, HttpOptions}

Http("http://example.com/search").param("q", "monkeys").asString

and an example of a POST:

和一个 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 is available through SBT:

Scalaj HTTP 可通过 SBT 获得:

libraryDependencies += "org.scalaj" % "scalaj-http_2.11" % "2.3.0"

回答by schmmd

You could use spray-client. The documentation is lacking (it took me some digging to find out how to make GET requests with query parameters) but it's a great option if you are already using spray. And the documentation is better than dispatch.

您可以使用spray-client。缺少文档(我花了一些时间才找到如何使用查询参数发出 GET 请求),但如果您已经在使用喷雾,这是一个不错的选择。而且文档比派遣好。

We're using it at AI2over dispatchbecause the operators are less symbolic and we're already using spray/actors.

我们在AI2over 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)

回答by drexin

I'm using dispatch: http://dispatch.databinder.net/Dispatch.html

我正在使用调度:http: //dispatch.databinder.net/Dispatch.html

They've just released a new version (0.9.0) with a complete new api that I really like. And it is async.

他们刚刚发布了一个带有我非常喜欢的全新 API 的新版本 (0.9.0)。它是异步的。

Example from project page:

来自项目页面的示例:

import dispatch._
val svc = url("http://api.hostip.info/country.php")
val country = Http(svc OK as.String)

for (c <- country)
  println(c)

edit: This might help you https://github.com/dispatch/reboot/blob/master/core/src/main/scala/requests.scala

编辑:这可能对你有帮助https://github.com/dispatch/reboot/blob/master/core/src/main/scala/requests.scala

回答by tksfz

Another option is Typesafe's play-ws, which is the Play Framework WS library broken out as a standalone lib:

另一种选择是 Typesafe 的 play-ws,它是作为独立库分解的 Play Framework WS 库:

http://blog.devalias.net/post/89810672067/play-framework-seperated-ws-library

http://blog.devalias.net/post/89810672067/play-framework-seperated-ws-library

I wouldn't necessarily offer this as the best option, but worth mentioning.

我不一定会将此作为最佳选择,但值得一提。

回答by Li Haoyi

Using my Requests-Scalalibrary:

使用我的Requests-Scala库:

// Mill
ivy"com.lihaoyi::requests:0.1.8"
// SBT
"com.lihaoyi" %% "requests" % "0.1.8"

This is as simple as

这很简单

val r = requests.get("https://api.github.com/users/lihaoyi")

r.statusCode
// 200

r.headers("content-type")
// Buffer("application/json; charset=utf-8")

r.text
// {"login":"lihaoyi","id":934140,"node_id":"MDQ6VXNlcjkzNDE0MA==",...
val r = requests.post("http://httpbin.org/post", data = Map("key" -> "value"))

val r = requests.put("http://httpbin.org/put", data = Map("key" -> "value"))

val r = requests.delete("http://httpbin.org/delete")

val r = requests.head("http://httpbin.org/head")

val r = requests.options("http://httpbin.org/get")

回答by Sanjay Bharwani

I had to do the same to test one end point (in Integration test). So following is the code to fetch response from GET request in Scala. I am making use of scala.io.Source to read from endpoint and ObjectMapper for json to object conversion.

我必须做同样的事情来测试一个端点(在集成测试中)。因此,以下是在 Scala 中从 GET 请求中获取响应的代码。我正在使用 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)

And here is my test method for the same

这是我的相同测试方法

test("validate booksMasterData resource") {
    val booksMasterData = fetchBooksMasterData(Option(null))
    booksMasterData.size should be (740)
  }

回答by Rick-777

If I can make a shameless plug, I have an API called Bee-Clientwhich is simply a wrapper in Scala for Java's HttpUrlConnection.

如果我可以做一个无耻的插件,我有一个名为Bee-Client的 API ,它只是 Scala 中 Java HttpUrlConnection 的一个包装器。

回答by Brian Agnew

Why not use Apache HttpComponents? Here's the application FAQ, which covers a wide range of scenarios.

为什么不使用Apache HttpComponents?这是应用程序常见问题解答,涵盖了广泛的场景。

回答by Abdelrahman Aly

Here is a class I was working on. It has both GET and POST requests. GET without parameters - POST with parameters I used it to communicate with StreamSets in order to start a pipeline or check a pipeline status.

这是我正在研究的一个类。它有 GET 和 POST 请求。不带参数的 GET - 带参数的 POST 我用它来与 StreamSets 通信以启动管道或检查管道状态。

it only need the following dependency in the build.sbt file:

它只需要 build.sbt 文件中的以下依赖项:

libraryDependencies += "org.scalaj" %% "scalaj-http" % "2.3.0"

You can find the documentation here: https://github.com/scalaj/scalaj-http#post-raw-arraybyte-or-string-data-and-get-response-code

您可以在此处找到文档:https: //github.com/scalaj/scalaj-http#post-raw-arraybyte-or-string-data-and-get-response-code


import scala.collection.mutable.ArrayBuffer
import scalaj.http.{Http, HttpResponse}

object HttpRequestHandler {

  val userName: String = "admin"
  val password: String = "admin"

  def sendHttpGetRequest(request: String): String = {

    println(" Send Http Get Request (Start) ")

    try {

      val httpResponse: HttpResponse[String] = Http(request).auth(userName,password)
                                                            .asString

      val response = if (httpResponse.code == 200) httpResponse.body
      else{
        println("Bad HTTP response: code = "+httpResponse.code )
        return "ERROR"
      }

      println(" Send Http Get Request (End) ")

      return response

    } catch {
      case e: Exception => println("Error in sending Get request: "+e.getMessage)
        return "ERROR"
    }


  }

  def arrayBufferToJson(params:ArrayBuffer[(String,String)]): String ={

    var jsonString = "{"
    var count: Int = 0
    for(param <- params){
      jsonString+="\""+param._1+"\":\""+param._2+"\""+ ( if(count!=params.length-1) "," else "")
      count+=1
    }
    jsonString+="}"

    return jsonString

  }

  def sendHttpPostRequest(request: String,params: ArrayBuffer[(String,String)]): String = {

    println(" Send Http Post Request (Start) ")

    try {
      val postData : String = arrayBufferToJson(params)
      println("Parameters: "+postData)
      val httpResponse: HttpResponse[String] = Http(request).auth(userName,password)
                                                            .header("X-Requested-By","sdc")
                                                            .header("Content-Type", "application/json;charset=UTF-8")
                                                            .header("X-Stream" , "true")
                                                            .header("Accept", "application/json")
                                                            .postData(postData.getBytes)
                                                            .asString


      val response = if (httpResponse.code == 200) httpResponse.body
      else{
        println("Bad HTTP response: code = "+httpResponse.code )
        "ERROR"
      }

      println(" Send Http Post Request (End) ")

      return response

    } catch {
      case e: Exception => println("Error in sending Post request: " + e.getMessage)
        return "ERROR"
    }
  }

}