Akka HTTP路径匹配 - pathEndOrSingleSlash似乎与

时间:2016-02-02 17:29:57

标签: regex scala akka akka-http

端点应回显请求路径的一部分。请求有两种变体:

<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'拒绝。

我想简单地忽略前缀,只需捕获传入任何路径的令牌。

1 个答案:

答案 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"
      }      
    }    
  }