我有一个受 Spray Scala 演示 here 启发的 API 类我正在编写将一个人呈现为喷雾 route 的 JSON 对象。
trait UsersApi {
case class Person(name: String, firstName: String, age: Int)
object MyJsonProtocol extends DefaultJsonProtocol {
implicit val PersonFormat = jsonFormat3(Person)
}
import MyJsonProtocol._
import spray.httpx.SprayJsonSupport._
import spray.util._
val bob = Person("Bob", "Parr", 32)
val usersApiRouting: Route = {
path("users") {
get {
complete {
marshal(bob)
}
}
}
}
}
问题是 marshal(bob) 像这样返回 JSON:
{
"name": "Bob",
"firstName": "Parr",
"age": 32
}
想象一下,我需要像这样呈现没有“年龄”的 JSON:
{
"name": "Bob",
"firstName": "Parr"
}
如何做到这一点?我的一个想法是 Scala 是否有办法制作一个对象,它是另一个对象的属性的子集?或者也许 spray-json 会对不编码不应添加到服务器响应中的属性提供一些特定的支持?
最佳答案
根据spray-json docs ,您应该提供这样的自定义 jsonFormat:
case class Person(name: String, firstName: String, age: Option[Int])
object MyJsonProtocol extends DefaultJsonProtocol {
implicit object PersonFormat extends RootJsonFormat[Person] {
def write(p: Person) =JsObject(
"name" -> JsString(p.name),
"firstName" -> JsString(p.firstName)
)
def read(value: JsValue) = {
value.asJsObject.getFields("name", "firstName", "age") match {
case Seq(JsString(name), JsString(firstName), JsNumber(age)) =>
new Person(name, firstName, Some(age.toInt))
case Seq(JsString(name), JsString(firstName)) =>
new Person(name, firstName, None)
case _ => throw new DeserializationException("Person expected: " + value.asJsObject.getFields("name", "firstName", "age").toString)
}
}
}
}
import MyJsonProtocol._
import spray.httpx.SprayJsonSupport._
import spray.util._
val bob = Person("Bob", "Parr", Some(32))
val bobJson = bob.toJson.toString //bobJson: String = {"name":"Bob","firstName":"Parr"}
val bobObj = bobJson.parseJson.convertTo[Person] //bobObj: Person = Person(Bob,Parr,None)
关于scala - 在 spray-json 中返回带有对象属性子集的 json 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25277169/