【问题标题】:Spray routing: How to respond with different content-types?喷雾路由:如何响应不同的内容类型?
【发布时间】:2014-01-14 16:22:54
【问题描述】:

在喷雾中,我想根据给定的Accept 标头来响应不同的内容类型。我在question by rompetroll 中看到了一些建议,但我想知道是否有任何规范的方法(即简单或已经实现)。

本质上我想应该发生的事情是这样的:

path("somepath") {
  get {
    // Find whatever we would like to return (lazily)
    ...
    // Marshall resource and complete depending on the `Accept` header
    ...
  }
}

提前致谢。

【问题讨论】:

    标签: scala routing http-headers spray http-accept-header


    【解决方案1】:

    查看测试in this commit

    我复制到这里供参考:

    case class Data(name: String, age: Int)
    object Data {
      import spray.json.DefaultJsonProtocol._
      import spray.httpx.SprayJsonSupport._
    
      // don't make those `implicit` or you will "ambiguous implicit" errors when compiling
      val jsonMarshaller: Marshaller[Data] = jsonFormat2(Data.apply)
      val xmlMarshaller: Marshaller[Data] =
        Marshaller.delegate[Data, xml.NodeSeq](MediaTypes.`text/xml`) { (data: Data) ⇒
          <data><name>{ data.name }</name><age>{ data.age }</age></data>
        }
    
      implicit val dataMarshaller: ToResponseMarshaller[Data] =
        ToResponseMarshaller.oneOf(MediaTypes.`application/json`, MediaTypes.`text/xml`)  (jsonMarshaller, xmlMarshaller)
    }
    

    然后,您在路由中使用 complete 就足够了,会自动处理内容类型协商:

    get {
      complete(Data("Ida", 83))
    }
    

    【讨论】:

    • 愚蠢的问题,但在上面的调用jsonFormat2(Data.apply) 中,.apply 定义在哪里?
    • 它由 Scala 编译器自动生成 case class 以支持 Data(...) 语法,而无需编写 new Data(...)
    【解决方案2】:

    Spray 实际上正在查看 Accept 标头值并针对它进行验证。因此,如果路由返回 application/jsontext/plain 并且客户端接受 image/jpeg,则 spray 将返回 406 Not Acceptable。如果客户端将从此路由请求application/jsontext/plain,那么他将收到具有匹配 Content-Type 的响应。

    这里的主要技巧是使用正确的编组器返回对象。 你可以阅读更多关于编组here的信息。

    您也可以使用 respondWithMediaType 指令覆盖 MediaType,但我认为最好使用正确的编组器。

    【讨论】:

    • 这很有意义。我完全错过了文档中的这一点。谢谢:)
    • 同意,respondWithMediaType 通常是错误的选择。 Marshallers 已经包含了进行自动内容类型协商的所有逻辑。请参阅我的答案,如何将不同内容类型的编组器组合成一个接受所有内容类型并为所有内容类型选择正确的编组器。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-01
    • 2014-08-20
    • 2013-05-11
    • 1970-01-01
    相关资源
    最近更新 更多