ビルドツールの設定
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
記事の執筆者にステッカーを贈る
有益な情報に対するお礼として、またはコメント欄における質問への返答に対するお礼として、 記事の読者は、執筆者に有料のステッカーを贈ることができます。
さらに詳しく →Feedbacks
ログインするとコメントを投稿できます。
関連記事
- Scala 文字列の処理書式指定 object Main { def main(args: Array[String]): Unit = { println("%d + %d = %d".format(1, 1, 2)) //=> 1 + 1 = 2 } } 文字列の比較 ヒアドキュメント 他の言語でいう「ヒアドキュメント」のようなものは """ で囲うことで実現できます。 object Main ...
- 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...
- 酢豚の基本的な使い方 (sbt)sbt は Scala および Java を主な対象としたビルドツールです。Scala Build Tool の略ではありませんが、Simple Build Tool という明示的な記述も公式ドキュメントなどには見当りません。以下 sbt の基本的な使用例をまとめます。使用した sbt のバージョンは 0.13 です。 公式ドキュメント [sbt 0.13](http://www.scala-sb...
- Scala 関数のサンプルコード「デフォルト引数」および「Unit 型を返す関数」 object HelloWorld { def main(args: Array[String]): Unit = { def myPrint(myArg: String = "default_value") = println(myArg + "!") val result = myPrint() //=> defau...
- Scala 組み込みの制御構造if-else 条件分岐で知られる if-else は三項演算子のようにも使用されます。 object HelloWorld { def main(args: Array[String]): Unit = { val myVal = if (!args.isEmpty) args(0) else "default" println(myVal) } ...