我正在尝试用纯喷雾罐+喷涂路线替换基于Jetty的后端。
前端使用text/json
媒体类型发布JSON内容。我和Jetty从来没有遇到任何问题。我刚刚意识到它不是一种标准类型,这要归功于spray,它只接受正确且标准的application/json
媒体类型。
有没有简单的方法可以在服务器端将一个映射到另一个?我真的希望避免引入应用程序客户端的临时版本来处理这个问题。当然,我会为下一个预定版本进行更改,但是现在我需要一个“快速而肮脏”的修复。
我尝试使用以下函数将标题从text/json
更改为application/json
:
def correctJsonHeaders(req:spray.http.HttpRequest) = {
val tweakedHeaders = req.headers.map{ hdr =>
if(hdr.name == "Content-Type" && hdr.value == "text/json")
`Content-Type`(`application/json`)
else
hdr
}
req.copy(headers = tweakedHeaders)
}
在我的路线指令中,如下:
path("route"){
mapRequest(correctJsonHeaders){
post{
respondWithMediaType(`application/json`) {
handleWith{ x:TypeThatUnmarshallsFromJson =>
bizLogicReturningAJsonString(x)
}
}
}
}
}
虽然标题已正确更改,但我仍然会收到415错误(如果我在客户端将媒体类型更改为application/json
,则会失败)
答案 0 :(得分:1)
在阅读了sp-http内容类型标题上的documentation之后,我将我的功能更改为:
def correctJsonHeaders(req:spray.http.HttpRequest) = {
if(req.headers.exists(hdr => hdr.name == "Content-Type" && hdr.value == "text/json")){
val tweakedEntity = spray.http.HttpEntity(`application/json`, req.entity.data)
req.copy(entity = tweakedEntity)
}
else req
}
似乎有用。诀窍是改变HttpEntity,而不是标题。
答案 1 :(得分:0)
缺少对自定义Accept和Content-Type标头的支持是由您使用的JSON编组器的实现引起的。看看这些特征的源代码,看看发生了什么:
只需通过实现自己的PlayJsonSupport特性并将自定义MediaType和ContentType添加到两个委托函数来解决此问题。我们也需要这个,因为我们将供应商版本放在我们的接受标头中,以支持我们的REST服务的版本控制。