Jen*_*olm 5 scala http-headers spray
嗨斯卡拉和喷人!
我有一个小烦人的问题,从RequestContext它上面提取HTTP'Accept'标题并进行匹配.在这样的正常路线上:
get {
respondWithMediaType(`text/plain`) {
complete ( "Hello World!" )
}
}
Run Code Online (Sandbox Code Playgroud)
它就像一个魅力.但每当我将上下文纳入范围时(如指令文档中所建议):
get { context => {
respondWithMediaType(`text/plain`) {
complete ( "Hello World!" )
}
} }
Run Code Online (Sandbox Code Playgroud)
结果将成为以下错误消息:
The server was not able to produce a timely response to your request.
Run Code Online (Sandbox Code Playgroud)
我对Spray很新,但对我来说看起来很奇怪,将一个(否则是隐式的)对象带入范围会产生如此奇怪的副作用.你们中有谁知道发生了什么事吗?
RequestContext很少需要直接访问.实际上,如果要编写自定义指令,则只需要它.通常可以使用预定义指令之一来处理常见任务和提取通常的数据位.
看来你想做的是手动内容类型协商.实际上,您不必手动执行此操作,因为喷涂会针对常见数据结构自动执行内容类型.你的例子可以缩短为
get {
complete("Hello World!")
}
Run Code Online (Sandbox Code Playgroud)
当complete使用字符串调用时,响应将始终为类型text/plain.如果客户端发送带有Accept不接受请求的标头text/plain的请求,则服务器已经拒绝该请求.
如果要自定义可从Scala数据类型提供的各种内容类型,则需要提供自定义Marshaller.请参阅有关如何实现这一目标的文档.
回答原始问题,为什么添加context =>会使请求超时:这是因为预定义指令已经是类型RequestContext => Unit.所以,写作
respondWithMediaType(`text/plain`) {
complete("Hello World!")
}
Run Code Online (Sandbox Code Playgroud)
完全等同于(即自动扩展到)
ctx => respondWithMediaType(`text/plain`) {
complete("Hello World!")
}.apply(ctx)
Run Code Online (Sandbox Code Playgroud)
因此,如果您只ctx =>手动添加,但不添加apply呼叫,则传入的请求永远不会进入内部路由,因此永远不会完成.编译器不会捕获此类错误,因为路由的类型是RequestContext => Unit,因此变量with和没有apply调用的变量都是有效的.我们将来会改进这一点.
有关如何构建路由的详细信息,请参阅文档.
最后,如果您需要提取标头或其值,您可以使用其中一个预定义的HeaderDirectives,它可以简化处理请求标头的过程.