developer tip

Scala에서 HTTP 요청 수행

copycodes 2020. 11. 4. 08:07
반응형

Scala에서 HTTP 요청 수행


Scala에서 일부 XML을 반환하는 웹 서비스에 간단한 POST 요청을 발행하려고합니다.

Dispatch 가이 작업에 사용되는 표준 라이브러리 인 것 같지만 문서를 찾을 수 없습니다. 위에서 링크 한 메인 사이트는 약속이 무엇인지, 비동기 프로그래밍을 수행하는 방법을 자세히 설명하지만 실제로 API를 문서화하지는 않습니다. 주기율표 가 있는데 -약간 무섭게 보이지만 이미 무엇을해야할지 알고 있고 비밀 구문에 대한 알림 만 필요한 사람들에게만 유용 해 보입니다.

또한 Scalaz에 HTTP대한 기능이있는 것 같지만 이에 대한 문서를 찾을 수 없습니다.


다음을 사용합니다 : 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"

spray-client를 사용할 수 있습니다 . 문서가 부족 하지만 ( 쿼리 매개 변수를 사용하여 GET 요청을 만드는 방법 을 알아 내기 위해 약간의 노력 이 필요했습니다) 이미 스프레이를 사용하고 있다면 훌륭한 옵션입니다. 그리고 문서는 파견보다 낫습니다.

오퍼레이터가 덜 상징적이고 이미 스프레이 / 액터를 사용하고 있기 때문에 우리는 AI2 에서 디스패치를 초과 하여 사용하고 있습니다.

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)

나는 dispatch를 사용하고 있습니다 : http://dispatch.databinder.net/Dispatch.html

그들은 내가 정말 좋아하는 완전히 새로운 API로 새 버전 (0.9.0)을 방금 출시했습니다. 그리고 그것은 비동기입니다.

프로젝트 페이지의 예 :

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

for (c <- country)
  println(c)

편집 : https://github.com/dispatch/reboot/blob/master/core/src/main/scala/requests.scala


또 다른 옵션은 Typesafe의 play-ws로, 독립형 lib로 분리 된 Play Framework WS 라이브러리입니다.

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

필자는 이것을 최선의 옵션으로 제공하지는 않지만 언급 할 가치가 있습니다.


Apache HttpComponents를 사용하지 않는 이유는 무엇 입니까? 다음 은 다양한 시나리오를 다루는 애플리케이션 FAQ 입니다.


뻔뻔한 플러그를 만들 수 있다면 Java의 HttpUrlConnection을위한 Scala의 래퍼 Bee-Client 라는 API 가 있습니다.


하나의 엔드 포인트를 테스트하기 위해 동일한 작업을 수행해야했습니다 (통합 테스트에서). 따라서 다음은 Scala의 GET 요청에서 응답을 가져 오는 코드입니다. scala.io.Source를 사용하여 json에서 객체로의 변환을 위해 끝점 및 ObjectMapper에서 읽습니다.

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)
  }

Requests-Scala 라이브러리 사용 :

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

이것은 간단합니다

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")

여기 제가 작업하고 있던 수업이 있습니다. GET 및 POST 요청이 모두 있습니다. 매개 변수없이 GET-매개 변수가있는 POST 파이프 라인을 시작하거나 파이프 라인 상태를 확인하기 위해 StreamSet과 통신하는 데 사용했습니다.

build.sbt 파일에 다음 종속성 만 필요합니다.

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

여기에서 설명서를 찾을 수 있습니다. 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"
    }
  }

}

참고URL : https://stackoverflow.com/questions/11719373/doing-http-request-in-scala

반응형