【问题标题】:How to match specific accept headers in a route?如何匹配路由中的特定接受标头?
【发布时间】:2013-10-02 06:57:43
【问题描述】:

我想创建一个仅在客户端发送特定 Accept 标头时才匹配的路由。我使用喷雾1.2-20130822

我想让路线正常运行:

def receive = runRoute {
    get {
      path("") {
        accept("application/json") {
           complete(...)
        }
      }
    }
  }

Here 我找到了一个使用accept() 函数的规范,但我不知道要在我的Spray-Handler 中导入什么以使其作为指令工作。此外,我没有找到其他有关标头指令的文档,但这些 stubs.

【问题讨论】:

    标签: scala spray


    【解决方案1】:

    我会这样做:

    def acceptOnly(mr: MediaRange*): Directive0 =
      extract(_.request.headers).flatMap[HNil] {
        case headers if headers.contains(Accept(mr)) ⇒ pass
        case _                                       ⇒ reject(MalformedHeaderRejection("Accept", s"Only the following media types are supported: ${mr.mkString(", ")}"))
      } & cancelAllRejections(ofType[MalformedHeaderRejection])
    

    然后只包装你的根:

    path("") {
      get {
        acceptOnly(`application/json`) {
          session { creds ⇒
            complete(html.page(creds))
          }
        }
      }
    }
    

    顺便说一句,最新的喷雾 1.2 nightly 是1.2-20130928,如果可以,请更新它

    【讨论】:

    • 这里有一个小错误:如果传入多个MediaRange 并且没有一个匹配,${mr: _*} 的字符串插值会失败。如果我将其更改为 ${mr} 它会运行,尽管输出现在包含 mr 的类型,这可能不是预期的。
    • @rompetroll 抱歉,不知道,谢谢。您可以将${mr: _*} 替换为${mr.mkString(", ")}
    【解决方案2】:

    没有称为accept 指令的预定义指令。你可以看到可用指令的完整列表here

    但是,您可以使用 headerValueByName 指令来创建一个自定义指令来满足您的需求:

    def accept(required: String) = headerValueByName("Accept").flatMap {
      case actual if actual.split(",").contains(required) => pass
      case _ => reject(MalformedHeaderRejection("Accept", "Accept must be equal to " + required))
    }
    

    将此代码放入您的喷雾Route 的范围内,然后按照您在问题中显示的方式使用。

    【讨论】:

    • 谢谢你应该工作。虽然我可能应该将if actual == required 更改为if actual.split(",") contains required 或类似的东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-04
    • 2018-06-10
    • 1970-01-01
    • 2015-12-28
    • 2018-04-18
    • 1970-01-01
    相关资源
    最近更新 更多