问题
In some cases default values make more sense than optionals in case classes:
case class Car(numberOfWheels:Int = 4, color:String)
case class Car(numbeOfWheels:Option[Int], color:String) //silly
In the first case I'd expect to be able to easily convert the following json to an instance:
{"color":"red"}
But with a standard jsonFormat2(Car)
, spray-json complains about missing value for numberOfWheels
.
How do I work around this most cleanly?
回答1:
I stumbled upon the same problem. I've create a patch that solves it for me. It makes fields with a default value optional.
https://github.com/spray/spray-json/pull/56
update: PR is updated and still open https://github.com/spray/spray-json/pull/93
回答2:
I have never used spray, but here's my guess about what may work:
case class Car(numberOfWheels: Int, color: String) {
def this(color: String) = this(4, color)
}
object Car {
def apply(color: String) = new Car(color)
}
Maybe now jsonFormat1(Car)
will work.
回答3:
The fix I found for the same issue was to implement my own jsonFormat:
implicit object carFormat extends JsonFormat[Car] {
def write(car: Car): JsObject = {
val fields = List(
("numberOfWheels" -> JsNumber(car.numberOfWheels)),
("color" -> JsString(car.color))
)
JsObject(fields: _*)
}
def read(json: JsValue): Car = {
val numberOfWheels = fromField[Option[Int]](json, "numberOfWheels")
val color = fromField[String](json, "color")
Car(numberOfWheels.getOrElse(4), color)
}
}
来源:https://stackoverflow.com/questions/15740925/what-is-a-good-way-to-handle-default-values-with-spray-json