Scala - как проходит путь вызова распыления (отладка кода распыления)

Я новичок в 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

Поэтому я не могу понять, почему программа входит во все возможные пути вызова, когда она началась. Кроме того, ни один из этих println не достигается при получении запроса HTTP.

Кто-нибудь может объяснить почему?

2 ответа

Решение

Вы можете найти объяснение здесь: Понимание извлечения

Короче говоря, неконечные и непараметрические (без извлечения) директивы выполняются только один раз при построении маршрута. Директива листа (как complete) выполняется, только если запрос попадает в маршрут директивы. Параметризованные директивы (и все внутри них) выполняются для каждого запроса (поскольку извлекаемый параметр каждый раз отличается), даже если сама директива идет после директивы, которая уже приняла этот запрос.

В вашем случае у вас есть printlns внутри неконечных и непараметрических директив, поэтому они выполнялись только один раз при инициализации. Если вы хотите, чтобы они выполнялись по приемлемому запросу - просто переместите их внутрь 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>
        }
    }
  }

Обсуждение здесь

Что ж, вы использовали "val" для объявления маршрутов распыления, это нормальное поведение, потому что когда вы запускаете вашу программу, инициализируйте val scals, если вы установите "lazy val" вместо "val", вы увидите, что вы получите печать, когда вы будете используйте этот 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
Другие вопросы по тегам