具体的
http://spray.io/documentation/1.2.3/spray-routing/advanced-topics/custom-directives/
通过自定义Directives更加方便我们拓展
这里从源码里挑出的一句概括
/**
* A Directive that always passes the request on to its inner route (i.e. does nothing).
*/
Directive的作用就是把request请求转给他内在的route
object Directive {
/**
* A Directive that always passes the request on to its inner route (i.e. does nothing).
*/
object Empty extends Directive0 {
<span style="BACKGROUND-COLOR: #ff0000"> def happly(inner: HNil ⇒ Route) = inner(HNil)
</span> }
implicit def pimpApply[L <: HList](directive: Directive[L])(implicit hac: ApplyConverter[L]): hac.In ⇒ Route = f ⇒ directive.happly(hac(f))
implicit class SingleValueModifiers[T](underlying: Directive1[T]) {
def map[R](f: T ⇒ R)(implicit hl: HListable[R]): Directive[hl.Out] =
underlying.hmap { case value :: HNil ⇒ f(value) }
def flatMap[R <: HList](f: T ⇒ Directive[R]): Directive[R] =
underlying.hflatMap { case value :: HNil ⇒ f(value) }
def require(predicate: T ⇒ Boolean, rejections: Rejection*): Directive0 =
underlying.filter(predicate, rejections: _*).hflatMap(_ ⇒ Empty)
def filter(predicate: T ⇒ Boolean, rejections: Rejection*): Directive1[T] =
underlying.hfilter({ case value :: HNil ⇒ predicate(value) }, rejections: _*)
}
}
那么我们通过自定义Directive来处理这个中间的request的内容
val intParameter: Directive1[Int] = parameter('a.as[Int])
val myDirective: Directive1[Int] =
intParameter.flatMap {
case a if a > 0 => provide(2 * a)
case _ => reject
}
通过parameter我们实际做了两件事情,定义转化参数以及reject不适合的请求
第二个Directive1
我们选择把参数加倍
或者直接合并两个
val intParameter: Directive1[Int] = parameter('a.as[Int]).flatMap {
case a if a > 0 => provide(2 * a)
}
追后我们把参数提给 complete作为追后的结果
intParameter.apply{ x =>
complete(x.toString)
}
整个代码:
import akka.actor.{Props, ActorSystem}
import akka.io.IO
import akka.util.Timeout
import spray.can.Http
import shapeless._
import spray.routing._
import Directives._
import spray.http._
import StatusCodes._
import scala.concurrent.duration._
object ActorTest5 extends App{
implicit val system = ActorSystem("mySystem")
val se = system.actorOf(Props[MyService2])
implicit val timeout = Timeout(5.seconds)
IO(Http) ! Http.Bind(se,interface = "localhost",port=8080)
}
class MyService2 extends HttpServiceActor {
val intParameter: Directive1[Int] = parameter('a.as[Int]).flatMap {
case a if a > 0 => provide(2 * a)
}
def receive = runRoute(route2)
val route2 = get{
path("color"){
intParameter.apply{ x =>
complete(x.toString)
}
}
}
}