私はJSONとの間でOption [String]フィールドをマーシャリングおよびアンマーシャリングしようとしています。私の使用事例では、None値を "null"としてマーシャリングする必要があります。ここで私が持っているコードは次のとおりです。Option [String]のJsonフォーマッタはありませんか?
import org.scalatest.{FlatSpec, Matchers}
import play.api.libs.json._
import play.api.libs.json.Reads._
import play.api.libs.functional.syntax._
case class Person(
id: Int,
firstName: Option[String],
lastName: Option[String]
)
object Person {
implicit lazy val personFormat = (
(__ \ "id").format[Int] and
(__ \ "first_name").format[Option[String]] and
(__ \ "last_name").format[Option[String]]
)(Person.apply, unlift(Person.unapply))
}
class PersonSpec extends FlatSpec with Matchers {
"When Person instance is marshaled None fields " should
"be serialized as \"null\" values" in {
val person = Person(1, None, None)
import Person._
val json = Json.toJson(person)
println(json)
(json \ "id").as[Int] should be (1)
(json \ "first_name").get should be (JsNull)
(json \ "last_name").get should be (JsNull)
}
}
これは、次のコンパイラエラーが発生:
PersonSpec.scala:19: No Json formatter found for type Option[String]. Try to implement an implicit Format for this type.
[error] (__ \ "first_name").format[Option[String]] and
[error] ^
はこれらは私がしようとしている事柄のいくつかである:(__ \ "first_name").formatNullable[String]
と(__ \ "first_name").format[Option[String]]
の交換
は、コンパイラを作ります幸いですが、次の出力(println(json)
)でテストに失敗します( "" java.util.NoSuchElementException:None.get "")
{"id":1}
これはformatNullable
の動作で確認されます(値なしフィールドは表示されません)。
次に、フォーマットをwrites
に置き換えました。同様に:
object Person {
implicit lazy val personWrite = (
(__ \ "id").write[Int] and
(__ \ "first_name").write[Option[String]] and
(__ \ "last_name").write[Option[String]]
)(unlift(Person.unapply))
}
コンパイラは満足しており、テストに合格しました。
しかし、今では別の読み取りを実装する必要があります。もしできれば、DRYの原則に違反するので、むしろそうしたいと思います。
[オプション[...]]が完全に機能する理由は何ですか?[オプション[...]]をフォーマットしないのはなぜですか?