モーダルを閉じる工作HardwareHub ロゴ画像

工作HardwareHubは、ロボット工作や電子工作に関する情報やモノが行き交うコミュニティサイトです。さらに詳しく

利用規約プライバシーポリシー に同意したうえでログインしてください。

工作HardwareHub ロゴ画像 (Laptop端末利用時)
工作HardwareHub ロゴ画像 (Mobile端末利用時)

Scala HTTP 通信

モーダルを閉じる

ステッカーを選択してください

モーダルを閉じる

お支払い内容をご確認ください

購入商品
」ステッカーの表示権
メッセージ
料金
(税込)
決済方法
GooglePayマーク
決済プラットフォーム
確認事項

利用規約をご確認のうえお支払いください

※カード情報はGoogleアカウント内に保存されます。本サイトやStripeには保存されません

※記事の執筆者は購入者のユーザー名を知ることができます

※購入後のキャンセルはできません

作成日作成日
2016/02/02
最終更新最終更新
2018/10/07
記事区分記事区分
一般公開

ビルドツールの設定

Dispatch を利用します。

pom.xml (maven)

<dependency>
  <groupId>net.databinder.dispatch</groupId>
  <artifactId>dispatch-core</artifactId>
  <version>0.11.2</version>
</dependency>
<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-classic</artifactId>
  <version>1.1.3</version>
</dependency>

build.sbt (sbt)

libraryDependencies ++= Seq(
  "net.databinder.dispatch" %% "dispatch-core" % "0.11.2",
  "ch.qos.logback" % "logback-classic" % "1.1.3"
)

とても簡単な例

同期しながら通信

import dispatch._, Defaults._

// 以下の二つと等価です:
// import dispatch._
// import dispatch.Defaults._

import java.lang.Thread

object Main {
  def main(args: Array[String]): Unit = {

    val svc = url("http://www.example.com")
    val future = Http(svc OK as.String)

    val f = future() // 同期

    println(f) //=> HTML 文字列
    println(f.length) //=> 1270
  }
}

非同期通信

import dispatch._, Defaults._
import java.lang.Thread

object Main {
  def main(args: Array[String]): Unit = {

    val svc = url("http://www.example.com")
    val future = Http(svc OK as.String)

    // レスポンスが得られてから実行されます。以下同様。
    for(f <- future)
      println(f)

    // Future[String] を Future[Int] に変換
    val futureLength = for(f <- future) yield f.length

    //
    // 完了しているかどうかで挙動が変化するメソッド
    //

    println(future.print) //=> Future(-incomplete-)
    println(futureLength.completeOption.getOrElse(-1)) //=> -1

    Thread.sleep(2000)

    println(future.print) //=> HTML 文字列
    println(futureLength.completeOption.getOrElse(-1)) //=> 1270
  }
}

様々な HTTP リクエストを構築

import dispatch._, Defaults._
import java.lang.Thread

object Main {
  def main(args: Array[String]): Unit = {

    // HTTP GET
    var req = url("http://www.example.com")

    // HTTPS GET
    var myHost = host("www.example.com")
    req = myHost.secure / "index.html"

    // HTTP ポート指定 GET
    myHost = host("www.example.com", 80)
    req = myHost / "index.html"

    // クエリパラメータの指定
    req = req.addQueryParameter("key", "value") // 記法1
    req = req <<? Map("key" -> "value") // 記法2

    // HTTP メソッド指定 (GET/POST/HEAD/PUT/PATCH/DELETE など)
    req = req.POST

    // Body 値の指定
    req = req.addParameter("key", "value") // 記法1
    req = req << Map("key" -> "value") // 記法2

    // 任意の文字列で Body 値を指定
    req = req.setContentType("application/json", "UTF-8")
    req = req << """{"key":"value"}"""

    // ファイル指定 (java.io.File) 
    // req = req.PUT
    // req = req <<< myFile

    val future = Http(req OK as.String)
    val f = future()
    println(f)
  }
}

複数の非同期通信

有限個

import dispatch._, Defaults._
import java.lang.Thread

object Main {
  def main(args: Array[String]): Unit = {

    val svc = url("http://www.example.com")
    val svc2 = url("http://www.example.com")

    val future = Http(svc OK as.String)
    val future2 = Http(svc2 OK as.String)

    val futureLength = for(f <- future) yield f.length
    val futureLength2 = for(f <- future2) yield f.length

    for {
      fl <- futureLength
      fl2 <- futureLength2
    } {
      println(fl == fl2) //=> true
    }

    def func(futureLength: Future[Int], futureLength2: Future[Int]) : Future[Boolean] = {
      for {
        fl <- futureLength
        fl2 <- futureLength2
      } yield fl == fl2
    }

    for(res <- func(futureLength, futureLength2))
      println(res) //=> true

    Thread.sleep(2000)
  }
}

無限個

import dispatch._, Defaults._
import java.lang.Thread

object Main {
  def main(args: Array[String]): Unit = {

    val svcList = List[String](
      "http://www.example.com/",
      "http://www.yahoo.co.jp/",
      "http://www.hatena.ne.jp"
    ).map(url(_))

    val futureList = for(svc <- svcList) yield Http(svc OK as.String) // map と同等の機能
    val futureLengthList =
      for(future <- futureList) yield // map と同等の機能
        for(f <- future) yield f.length // Future[String] から Future[Int] への変換

    val longest =
      for(lengthList <- Future.sequence(futureLengthList)) yield // List[Future[Int]] から Future[Int] への変換
        lengthList.max // List の機能

    for(l <- longest)
      println(l) //=> 96157

    Thread.sleep(2000)
  }
}

例外処理

Option 型を用いた例外処理

.option を利用すると Option 型の Future が取得できます。

import dispatch._, Defaults._

object Main {
  def main(args: Array[String]): Unit = {

    val svc = url("http://www.example.com") // 存在するホスト
    // val svc = url("http://dummy.example.com") // 存在しないホスト

    val future = Http(svc OK as.String).option // Future[Option[String]]

    val f = future()

    val html = f match {
      case Some(html) => html // www.example.com
      case None => null // dummy.example.com
    }
    println(html)
  }
}

onComplete を用いた例外処理

import dispatch._, Defaults._
import scala.util.{Success, Failure}

import java.lang.Thread

object Main {
  def main(args: Array[String]): Unit = {

    val svc = url("http://www.example.com") // 存在するホスト
    // val svc = url("http://dummy.example.com") // 存在しないホスト

    val future = Http(svc OK as.String)

    future.onComplete {
      case Success(html) => { // www.example.com
        println(html)
      }
      case Failure(e) => { // dummy.example.com
        println("エラーが発生しました: " + e.getMessage)
      }
    }

    Thread.sleep(2000)
  }
}
0
詳細設定を開く/閉じる
アカウント プロフィール画像 (本文下)

Scalaはいいぞ

記事の執筆者にステッカーを贈る

有益な情報に対するお礼として、またはコメント欄における質問への返答に対するお礼として、 記事の読者は、執筆者に有料のステッカーを贈ることができます。

さらに詳しく →
ステッカーを贈る コンセプト画像

Feedbacks

Feedbacks コンセプト画像

    ログインするとコメントを投稿できます。

    関連記事

    • Scala 文字列の処理
      書式指定 object Main { def main(args: Array[String]): Unit = { println("%d + %d = %d".format(1, 1, 2)) //=> 1 + 1 = 2 } } 文字列の比較 ヒアドキュメント 他の言語でいう「ヒアドキュメント」のようなものは """ で囲うことで実現できます。 object Main ...
      したくんしたくん6/18/2018に更新
      いいねアイコン画像0
    • Scala 日付に関する処理
      Date クラスを文字列にフォーマット import java.util.Date object Main { def main(args: Array[String]): Unit = { // format は Date に限らない文字列用の機能です。 println("%d-%d-%d" format (1, 1, 1)) //=> 1-1-1 printl...
      したくんしたくん6/5/2018に更新
      いいねアイコン画像0
    • 酢豚の基本的な使い方 (sbt)
      sbt は Scala および Java を主な対象としたビルドツールです。Scala Build Tool の略ではありませんが、Simple Build Tool という明示的な記述も公式ドキュメントなどには見当りません。以下 sbt の基本的な使用例をまとめます。使用した sbt のバージョンは 0.13 です。 公式ドキュメント [sbt 0.13](http://www.scala-sb...
      ねこねこ6/30/2018に更新
      いいねアイコン画像0
    • Scala 関数のサンプルコード
      「デフォルト引数」および「Unit 型を返す関数」 object HelloWorld { def main(args: Array[String]): Unit = { def myPrint(myArg: String = "default_value") = println(myArg + "!") val result = myPrint() //=> defau...
      したくんしたくん6/26/2018に更新
      いいねアイコン画像0
    • Scala 組み込みの制御構造
      if-else 条件分岐で知られる if-else は三項演算子のようにも使用されます。 object HelloWorld { def main(args: Array[String]): Unit = { val myVal = if (!args.isEmpty) args(0) else "default" println(myVal) } ...
      したくんしたくん10/7/2021に更新
      いいねアイコン画像0