我正在使用json4s的喷雾,我已经得到了下面的实现来处理更新对象的put请求...我的问题是,我首先从json中提取SomeObject的实例,但是RESTful api,我希望在URL中指定ID。所以我必须以某种方式创建另一个使用ID索引的SomeObject实例...为此,我使用像SomeObject这样的构造函数(id:Long,obj:SomeObject)。它工作得很好,但实现很难看,而且感觉效率低下。我能做什么才能以某种方式将ID粘贴在那里,以便我只创建一个SomeObject实例?
class ApplicationRouter extends BaseRouter {
val routes =
pathPrefix("some-path") {
path("destination-resource" \ IntNumber) { id =>
entity(as[JObject]) { rawData =>
val extractedObject = rawData.camelizeKeys.extract[SomeObject]
val extractedObjectWithId = SomeObject(id, extractedObject)
handleRequest(extractedObjectWithId)
}
}
}
}
case class SomeObject(id: Long, data: String, someValue: Double, someDate: DateTime) {
def this(data: String, someValue: Double, someDate: DateTime) = this(0, data, someValue, someDate)
def this(id: Long, obj: SomeObject) = this(id, obj.data, obj.someValue, obj.someDate)
}
答案 0 :(得分:1)
在经过一段时间的文档挖掘后,我想出了一个解决方案:
class ApplicationRouter extends BaseRouter {
val routes =
pathPrefix("some-path") {
path("destination-resource" \ IntNumber) { id =>
entity(as[JObject]) { rawData =>
val extractedObject = rawData.camelizeKeys.merge {
("id", id)
}.extract[SomeObject]
handleRequest(extractedObject)
}
}
}
}
答案 1 :(得分:0)
由于未在所有实例上设置id字段,因此它表示它是可选的,因此请使用Option
类型来指示它。使用id: Option[Long]
字段定义案例类。这使得json解析器在不存在时跳过id字段,但允许你在有时分配一个值。
case class SomeObject(id: Option[Long], data: String, someValue: Double, someDate: DateTime)
class ApplicationRouter extends BaseRouter {
val routes =
pathPrefix("some-path") {
path("destination-resource" \ IntNumber) { id =>
entity(as[JObject]) { rawData =>
val extractedObject = rawData.camelizeKeys.extract[SomeObject]
val extractedObjectWithId = extractedObject.copy(id = Some(id))
handleRequest(extractedObjectWithId)
}
}
}
}
并且不要担心创建新对象对性能的影响。它可能会比你想象的更少地影响性能。您应该在改进之前测量性能。
答案 2 :(得分:-1)
我不知道效率,但是你可以让你的代码变得更加难看"通过定义SomeObjectBuilder
,您可以将JSON值提取到其中。
case class SomeObjectBuilder(data: String, someValue: Double, someDate: DateTime) {
def setId(id: Long) = SomeObject(id, data, someValue, someDate)
}
case class SomeObject(id: Long, data: String, someValue: Double, someDate: DateTime)
提取:
class ApplicationRouter extends BaseRouter {
val routes =
pathPrefix("some-path") {
path("destination-resource" \ IntNumber) { id =>
entity(as[JObject]) { rawData =>
val extractedObject = rawData.camelizeKeys.extract[SomeObjectBuilder]
val extractedObjectWithId = extractedObject.setId(id)
handleRequest(extractedObjectWithId)
}
}
}
}
这样,您没有将默认id
设置为零,如果我理解正确,则永远不会更正。您将其设置为零的唯一原因是提取器不知道该值,因此,使用构建器,您可以显式部分实例化。