在喷涂中,我想根据给定的Accept
标题回复不同的内容类型。我在question by rompetroll中看到了一些建议,但我想知道是否有任何规范的方法(即简单或已经实施)。
本质上我想象的应该是:
path("somepath") {
get {
// Find whatever we would like to return (lazily)
...
// Marshall resource and complete depending on the `Accept` header
...
}
}
提前致谢。
答案 0 :(得分:15)
参见测试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))
}
答案 1 :(得分:8)
Spray实际上正在调查Accept
标头值并对其进行验证。因此,如果路线返回application/json
或text/plain
而客户接受image/jpeg
,则会返回406 Not Acceptable
。如果客户从此路线请求application/json
或text/plain
,则他将收到匹配内容类型的回复。
这里的主要技巧是使用正确的marshallers作为返回对象。 您可以阅读有关编组here的更多信息。
此外,您可以使用respondWithMediaType指令覆盖MediaType,但我认为最好使用正确的marshallers。