我有一个方案,其中路由包含键/值对的交替段。对的数量不确定,收集这些对的有效方法是什么。例如,路线可能看起来像
/key1/value1/key2/value2/key3/value3
我想获得一个链接图
(key1, value1) -> (key2, value2) -> (key3, value3)
我知道我们可以获取路径段的列表并按上述方式进行转换。但是我正在寻找的是一种可以向下导航的东西
class EntitiesSpec extends WordSpec with Matchers with ScalatestRouteTest with Directives {
def lastSegment:Directive1[String] = path(Segment)
def intermediate: Directive1[String] = <processing the intermediate>
val navigate = (intermediate & navigate) ~ lastSegment
val route = navigate { (param1:String) =>
complete(param1)
}
"this should call the route" should {
"invoke a route /hello" in {
Get("/hello/world/hello1/world1/hello3/world3") ~> route ~> check {
println(responseAs[String])
}
}
}
}
例如,如果您有一条类似的路径,
/12/1/5/6/8
如何定义可以递归添加数字的指令?任何帮助表示赞赏。
答案 0 :(得分:2)
不要为键/值对使用路径
问题中描述的方法是一种反模式。在query string中,键/值配对可以轻松完成。通过使用parameterMap
指令,将键/值对转换为String
元组的列表变得很简单:
//matches a uri of the form: /?key1=value1&key2=value2
val queryStringRoute =
parameterMap { params =>
val linkedPairList : List[(String, String)] = params.toList
}
不要在指令上使用递归
递归指令也是不明智的。 A Route
is declared as a simple Function1
:
type Route = (RequestContext) ⇒ Future[RouteResult]
由于返回类型为Future
,因此任何递归都必须是对原始Future的操作。因此,原始调用堆栈不能被忽略,并且递归将永远不会被尾部优化。如果路径足够长,则可能导致递归函数的堆栈溢出。
如果必须使用路径
如果除了使用Path
别无选择,则可以进行一些String
解析:
val pathToKeyValuePairs : Uri.Path => List[(String, String)] =
(_ : Uri.Path)
.toString
.split('/')
.grouped(2)
.map(arr => arr(0) -> arr(1))
.toList
此解析器现在可以在Route
内部使用:
val unadvisedRoute =
extractRequest { request =>
val linkedPairList : List[(String, String)] =
pathToKeyValuePairs(request.uri.path)
}