在Spray 1.2.0路由中将查询字符串参数与JSON实体相结合
使用Spray路由,我希望有一个将查询字符串参数与JSON实体合并的指令,两者都是可选的。我希望在任何编组发生之前发生这种情况 大概是这样的:在Spray 1.2.0路由中将查询字符串参数与JSON实体相结合,json,scala,spray,spray-json,spray-dsl,Json,Scala,Spray,Spray Json,Spray Dsl,使用Spray路由,我希望有一个将查询字符串参数与JSON实体合并的指令,两者都是可选的。我希望在任何编组发生之前发生这种情况 大概是这样的: val myRoute = mergedParametersAndEntity(as[DomainSpecificClass]) { myobj => // ... code code code ... complete(OK, myobj.someMethod) } 基本上我希望的是以下行为: 当有人提出以下请求时: POST /v1/
val myRoute = mergedParametersAndEntity(as[DomainSpecificClass]) { myobj =>
// ... code code code ...
complete(OK, myobj.someMethod)
}
基本上我希望的是以下行为:
当有人提出以下请求时:
POST /v1/resource?a=helloQS&b=helloQS
Content-Type: application/json
{"a":"helloFromJson","c":"helloFromJson"}
然后上面的对象(myobj
)可以包含键:
a -> helloFromJson
b -> helloQS
c -> helloFromJson
换句话说,请求正文中指定的项将覆盖查询字符串中的内容。我知道这一定是可能的,但我就是不知道怎么做。有人能帮忙吗
谢谢大家! 我的建议是:不要采取这种方法。它摸起来很脏。如果可以的话,回到绘图板上 考虑到这一点,您将无法使用Spray中现有的JSON编组支持插入所需的合并。你需要自己把它缝在一起。这样的事情至少应该为你指明正确的方向(前提是你必须走的方向):
如果有人还想知道如何做到这一点,这里有一个小的Spray指令,它允许在解包之前将param值复制到JSON。它使用JSON()在解组之前修改请求主体
def updateJson(update: Update): Directive0 = {
mapRequest((request: HttpRequest) => {
request.entity match {
case Empty => request
case NonEmpty(contentType, data) =>
try {
request.copy(entity = HttpEntity(`application/json`, JsonParser(data.asString).update(update).toString))
}
catch {
case e: ParsingException => request
}
}
})
}
下面是你如何使用它。假设您希望使用PUT请求更新资源,并将ID从URL传递到解组器(顺便说一句,这是一种非常常见的情况):
您还可以将其与parameters
指令结合使用,以设置任意GET参数
def updateJson(update: Update): Directive0 = {
mapRequest((request: HttpRequest) => {
request.entity match {
case Empty => request
case NonEmpty(contentType, data) =>
try {
request.copy(entity = HttpEntity(`application/json`, JsonParser(data.asString).update(update).toString))
}
catch {
case e: ParsingException => request
}
}
})
}
// Model
case class Thing(id: Long, title: String, description: String, createdAt: DateTime)
// Actor message for the update operation
case class UpdateThing(id: Long, title: String)
// Spray routing
def thingsRoute =
path("things" / Segment) { id =>
put {
updateJson(field("id") ! set[Long](id)) {
entity(as[UpdateThing]) { updateThing =>
complete {
// updateThing now has the ID set
(someActor ? updateThing).mapTo[Thing]
}
}
}
}
}