1

Scala、Spray、および関数型プログラミングは初めてです。そして、Spray RestAPI の基本的な例をいまだに理解できないのはとても悲しいことです。

このブログ投稿の指示に従ってプログラムを作成しました。 http://www.smartjava.org/content/first-steps-rest-spray-and-scala

私のルート機能は次のとおりです。

  val aSimpleRoute =
    path("path1") {
      println("in path path1..")
      put {
        println("in path path1/put..")
        respondWithMediaType(MediaTypes.`text/html`) {
          complete {
            <h1>in path path1/put..</h1>
          }
        }
      } ~ get {
        println("in path path1/get..")
        respondWithMediaType(MediaTypes.`application/json`) {
          complete {
            <h1>in path path1/get..</h1>
          }
        }
      }
    } ~
  path("path2") {
    println("in path path2..")
    get {
      println("in path path2/get..")
      respondWithMediaType(MediaTypes.`application/json`) {
        complete {
          <h1>in path path2/get..</h1>
        }
      }
    } ~ post {
      println("in path path2/post..")
      respondWithMediaType(MediaTypes.`application/json`) {
        complete {
          <h1>in path path2/post..</h1>
        }
      }
    }
  }

すべてが期待どおりに機能します。しかし、私の問題は、私のプログラムが開始されると、受信機能を介して実行されることです。プログラムが開始されたときのprintlnの出力を参照してください(httpリクエストを処理する前)

in path path1..
in path path1/put..
in path path1/get..
in path path2..
in path path2/get..
in path path2/post..
[INFO] [09/14/2015 12:56:01.364] [on-spray-can-akka.actor.default-dispatcher-4] [akka://on-spray-can/user/IO-HTTP/listener-0] Bound to localhost/127.0.0.1:8080

そのため、プログラムが開始されたときに、プログラムが可能なすべての呼び出しパスに入る理由を理解できません。また、HTTP リクエストを受信したときに、これらの println のいずれにも到達しません。

誰でも理由を説明できますか?

4

2 に答える 2

2

ここで説明を見つけることができます:抽出について

つまり、非リーフおよび非パラメーター化 (抽出なし) のディレクティブは、ルートのビルド時に 1 回だけ実行されます。リーフ ディレクティブ ( などcomplete) は、リクエストがディレクティブのルートにヒットした場合にのみ実行されます。パラメーター化されたディレクティブ (およびその中のすべて) は、要求ごとに実行されます (抽出されたパラメーターは毎回異なるため) - ディレクティブ自体が、この要求を既に受け入れたディレクティブの後に来る場合でも。

あなたの場合、printlnリーフ以外のパラメータ化されていないディレクティブ内に s があるため、初期化時に一度だけ実行されました。受け入れ可能なリクエストごとにそれらを実行したい場合は、それらを内部に移動するだけcompleteです:

val aSimpleRoute =
  path("path1") {
    put {     
      respondWithMediaType(MediaTypes.`text/html`) {
        complete {
          println("in path path1/put..")
          <h1>in path path1/put..</h1>
        }
      }
    } ~ get {
      respondWithMediaType(MediaTypes.`application/json`) {
        complete {
          println("in path path1/get..")
          <h1>in path path1/get..</h1>
        }
      }
    }
  } ~
  path("path2") {
    get {    
      respondWithMediaType(MediaTypes.`application/json`) {
        complete {
          println("in path path2/get..")
          <h1>in path path2/get..</h1>
        }
      }
    } ~ post {
      respondWithMediaType(MediaTypes.`application/json`) {
        complete {
          println("in path path2/post..")
          <h1>in path path2/post..</h1>
        }
    }
  }

ディスカッションはこちら

于 2015-09-14T08:32:13.110 に答える
1

"val" を使用してスプレー ルートを宣言しました。プログラムを実行すると、Scala が val を初期化するため、これは通常の動作です。この値を明示的に使用します。

例えば:

    val a = {
        println("val a initialization")
        "val a initialization"
      }
 
   lazy val b = {
        println("using of val b")
        "using of val b"
      }
    
      println("use of Val a " + a)
    
      println("use of val b  " + b)

結果:

val a initialization
use of Val a val a initialization
using of val b
use of val b  using of val b
于 2015-09-14T08:19:31.483 に答える