about 8 years ago
繼第一篇scala、spray、IntelliJ環境安裝篇後,要來建置第一個spray應用了
開啟IntelliJ選擇Create New Project
選擇Scala專案並使用SBT
新建一個test1的專案
先在project\plugins.sbt增加外掛
logLevel := Level.Warn
addSbtPlugin("io.spray" % "sbt-revolver" % "0.7.1")
addSbtPlugin("com.timushev.sbt" % "sbt-updates" % "0.1.2")
開啟build.sbt做編輯,右上角會出現Refresh就按下去讓他去重整抓取相關套件吧
name := "test1"
version := "1.0"
scalaVersion := "2.11.4"
scalacOptions := Seq("-unchecked", "-deprecation", "-encoding", "utf8")
resolvers ++= Seq(
"Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/",
"Spray repository" at "http://repo.spray.io/"
)
libraryDependencies ++= {
val akkaV = "2.3.7"
val sprayV = "1.3.2"
Seq(
//"org.java-websocket" % "Java-WebSocket" % "1.3.1",
"org.json4s" % "json4s-native_2.11" % "3.2.11",
"io.spray" % "spray-json_2.11" % "1.3.1",
"io.spray" % "spray-can_2.11" % sprayV,
"io.spray" % "spray-routing_2.11" % sprayV,
"com.typesafe.akka" % "akka-actor_2.11" % akkaV,
"com.typesafe.akka" % "akka-testkit_2.11" % akkaV % "test",
"io.spray" % "spray-testkit_2.11" % sprayV % "test",
"org.scalatest" % "scalatest_2.11" % "2.2.2" % "test",
"junit" % "junit" % "4.11" % "test",
//"org.specs2" % "specs2_2.11" % "2.4.13" % "test",
"org.specs2" % "specs2-core_2.11" % "2.4.13" % "test"
)
}
新增一個檔案src\main\resources\application.conf,這是一些參數配置
akka {
loglevel = INFO
}
spray.can.server {
request-timeout = 1s
}
新增套件
在範例套件底下新增MyService.scala,但是這支成是我們先定為介面,之後再來新增MyServiceActor
package com.example
import akka.actor.Actor
import spray.routing._
import spray.http._
import MediaTypes._
// we don't implement our route structure directly in the service actor because
// we want to be able to test it independently, without having to spin up an actor
class MyServiceActor extends Actor with MyService {
// the HttpService trait defines only one abstract member, which
// connects the services environment to the enclosing actor or test
def actorRefFactory = context
// this actor only runs our route, but you could add
// other things here, like request stream processing
// or timeout handling
def receive = runRoute(myRoute)
}
// this trait defines our service behavior independently from the service actor
trait MyService extends HttpService {
val myRoute =
path("") {
get {
respondWithMediaType(`text/html`) { // XML is marshalled to `text/xml` by default, so we simply override here
complete {
<html>
<body>
<h1>Say hello to <i>spray-routing</i> on <i>spray-can</i>!</h1>
</body>
</html>
}
}
}
}
}
下面的Kind要選擇Trait
新增trait的實做內容
新增class MyServiceActor,這邊要注意他在寫在MyService.scala之內,可以寫在一起的
最後再一個啟動伺服器的物件src\main\scala\com\example\Boot.scala
package com.example
import akka.actor.{ActorSystem, Props}
import akka.io.IO
import spray.can.Http
import akka.pattern.ask
import akka.util.Timeout
import scala.concurrent.duration._
object Boot extends App {
// we need an ActorSystem to host our application in
implicit val system = ActorSystem("on-spray-can")
// create and start our service actor
val service = system.actorOf(Props[MyServiceActor], "demo-service")
implicit val timeout = Timeout(5.seconds)
// start a new HTTP server on port 8080 with our service actor as the handler
IO(Http) ? Http.Bind(service, interface = "localhost", port = 8080)
}
新增測試類別src\test\scala\com\example\MyServiceSpec.scala
package com.example
import org.specs2.mutable.Specification
import spray.testkit.Specs2RouteTest
import spray.http._
import StatusCodes._
class MyServiceSpec extends Specification with Specs2RouteTest with MyService {
def actorRefFactory = system
"MyService" should {
"return a greeting for GET requests to the root path" in {
Get() ~> myRoute ~> check {
responseAs[String] must contain("Say hello")
}
}
"leave GET requests to other paths unhandled" in {
Get("/kermit") ~> myRoute ~> check {
handled must beFalse
}
}
"return a MethodNotAllowed error for PUT requests to the root path" in {
Put() ~> sealRoute(myRoute) ~> check {
status === MethodNotAllowed
responseAs[String] === "HTTP method not allowed, supported methods: GET"
}
}
}
}
你就可以直接啟動服務了,在這邊查看http://127.0.0.1:8080/