Scala 使用akka http路由dsl提取路径参数

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与指令路径(“我的”/“路径”)不匹配 下面的解决方案通过从请求上下文中删除路径参数来解决这个问题

Akka HTTP在路由dsl中很好地支持提取路径查询参数(在?之后的参数,由&)连接),但不支持由分隔的路径参数;(例如/my/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))