Scala 使用akka http路由dsl提取路径参数
Akka HTTP在路由dsl中很好地支持提取路径查询参数(在?之后的参数,由&)连接),但不支持由分隔的路径参数;(例如/my/path;JSESSIONID=123)Scala 使用akka http路由dsl提取路径参数,scala,http,akka,akka-http,Scala,Http,Akka,Akka Http,Akka HTTP在路由dsl中很好地支持提取路径查询参数(在?之后的参数,由&)连接),但不支持由分隔的路径参数;(例如/my/path;JSESSIONID=123) 这是如何最好地完成的?比我想象的容易。可能会删除对scalaz(Lens)的依赖,并对代码进行一点优化,但现在就可以了 顺便说一句,还发现path参数破坏了将路径与path指令匹配的能力: /我的道路;JSESSIONID=123与指令路径(“我的”/“路径”)不匹配 下面的解决方案通过从请求上下文中删除路径参数来解决这个问题
这是如何最好地完成的?比我想象的容易。可能会删除对scalaz(Lens)的依赖,并对代码进行一点优化,但现在就可以了 顺便说一句,还发现path参数破坏了将路径与path指令匹配的能力: /我的道路;JSESSIONID=123与指令路径(“我的”/“路径”)不匹配 下面的解决方案通过从请求上下文中删除路径参数来解决这个问题,而不是提供它们 请注意:也许您可以在框架中加入类似的东西,以便下一个从路径参数获取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))