端点应回显请求路径的一部分。请求有两种变体:
<host>/xyz-<token>/
<host>/xyz-<token>.txt
token
部分是我想要提取的部分。但是,我只能匹配第二个变体,而不是第一个。该请求被'The requested resource could not be found'
拒绝。斜杠似乎阻止了匹配。当我从第一个变体中删除斜杠时,它匹配,当我向第二个变量添加斜杠时,它会停止匹配。我尝试了几种变体,最简单的可重复性是:
val tokenRoute: Route =
pathSuffix(s"xyz-(.+)".r) { token: String =>
pathEndOrSingleSlash {
complete(token.split('.').head)
}
}
在正则表达式的末尾添加或删除斜杠似乎没有任何效果。也不删除pathEndOrSingleSlash
指令。
我在这里误解了什么?
编辑:
我一直过于简单化 - 匹配的路径也应包括
<host>/<prefix>/xyz-<token>/
<host>/<prefix>/xyz-<token>.txt
pathPrefix
未处理的 - 包含前缀的请求(例如<host>/abc/xyz-<token>/
)将被'The requested resource could not be found'
拒绝。
我想简单地忽略前缀,只需捕获传入任何路径的令牌。
答案 0 :(得分:2)
我认为你打算使用的是pathPrefix
而不是pathSuffix
。如果您将路线更改为以下代码,我相信事情将开始为您服务:
pathPrefix(s"xyz-(.+)".r) { token: String =>
pathEndOrSingleSlash {
complete(token.split('.').head)
}
}
修改强>
我的原始答案不会处理OP编辑中提到的情况。如果需要匹配的前导路径元素中存在可变性,则最好从路径的后端而不是前端开始工作,然后返回使用pathSuffix
。以下是如何使用基于后缀的匹配,包括一些测试场景,以显示正确处理哪种路径:
val route:Route =
pathSuffix(Slash.?){
pathSuffix(s"xyz-(.+)".r) { token: String =>
complete(token.split('.').head)
}
}
"A request to my route" should{
"handle the route ending with a dot extension and no trailing slash" in {
Get("/xyz-foo.txt") ~> route ~> check{
handled ==== true
responseAs[String] ==== "foo"
}
}
"handle the route with no dot extension and having a trailing slash" in {
Get("/xyz-foo/") ~> route ~> check{
handled ==== true
responseAs[String] ==== "foo"
}
}
"handle a number of prefix elements in the path and end in a single slash" in {
Get("/hello/world/xyz-foo/") ~> route ~> check{
handled ==== true
responseAs[String] ==== "foo"
}
}
"handle a number of prefix elements in the path and end with a dot extension" in {
Get("/hello/world/xyz-foo.txt") ~> route ~> check{
handled ==== true
responseAs[String] ==== "foo"
}
}
}