almost 3 years ago

繼第一篇scala、spray、IntelliJ環境安裝篇後,要來建置第一個spray應用了

開啟IntelliJ選擇Create New Project

選擇Scala專案並使用SBT

新建一個test1的專案

先在project\plugins.sbt增加外掛

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就按下去讓他去重整抓取相關套件吧

build.sbt
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,這是一些參數配置

application.conf
akka {
  loglevel = INFO
}

spray.can.server {
  request-timeout = 1s
}



新增套件


在範例套件底下新增MyService.scala,但是這支成是我們先定為介面,之後再來新增MyServiceActor

MyService.scala
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

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

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/



spray模板

← logback試用 Java 操作Zip壓縮 →
 
comments powered by Disqus