2015-08-18 31 views
1

阿卡HTTP提取路徑參數具有用於提取路徑查詢參數在路由DSL良好的支持(那些跟隨,通過&級聯?),但不用於通過分離的路徑參數; (比如/ my/path; JSESSIONID = 123)與阿卡HTTP路由DSL

這是如何最好地完成的?

回答

2

比我想象的容易。可能可能會取消對scalaz(Lens)的依賴並稍微優化一些代碼,但現在這樣做。

順便說一句,也發現該路徑PARAMS破壞以匹配與該路徑指令的路徑的能力: /我的/路徑; JSESSIONID = 123不匹配指令路徑(「我的」 /「路徑」)

下面的解決方案通過從請求上下文中刪除路徑參數來解決這個問題,而是提供它們。

請注意Akka傢伙:也許你可以在框架中加入類似的東西,以便下一個從路徑參數中獲取JSESSIONID的人不必實現相同的目標?

def pathParams: Directive1[List[String]] = { 
    val prv = provide(List.empty[String]) 
    def somePathParams(ctxPathLens: Lens[RequestContext, Path]) = 
     extract(ctx => (Slash ~ Segments).apply(ctxPathLens.get(ctx))).flatMap { 
     case Matched(_, Tuple1(path)) => 
      path.takeRight(1) match { 
      case last :: Nil => last.split(';').toList match { 
       case lastHead :: lastTail => provide(lastTail) & mapRequestContext(
       ctxPathLens.set(_, Path((path.dropRight(1) :+ lastHead).mkString("/", "/", "")))) 
       case _ => prv 
      } 
      case _ => prv 
      } 
     case _ => prv 
     } 

    val unmatchedPath = somePathParams(Lens.lensu((ctx, path) => 
     ctx.mapUnmatchedPath(_ => path), 
     _.unmatchedPath)) 

    val requestPath = somePathParams(Lens.lensu((ctx, path) => 
     ctx.mapRequest(r => r.withUri(r.uri.withPath(path))) 
     , _.request.uri.path)) 

    unmatchedPath.tflatMap(_ => Directive.Empty) & requestPath 
    } 

    def pathParamsMap: Directive1[Map[String, String]] = 
    pathParams.map(_.map(_.split('=').toList match { 
     case key :: Nil => key -> "" 
     case key :: values => key -> values.mkString("=") 
     case _ => ??? 
    }).toMap) 

    def optionalPathParam(name: String): Directive1[Option[String]] = 
    pathParamsMap.map(_.get(name)) 

    def optionalPathParamSessionId:Directive1[Option[UUID]] = 
    optionalPathParam(jsessionidKey).map(_.flatMap(j => Try(UUID.fromString(j)).toOption))