scala 使用Play Framework 2.1在JsObject中为Option设置值

ttcibm8c  于 5个月前  发布在  Scala
关注(0)|答案(2)|浏览(69)

我有一个案例类与一些可选的:

case class Person (
  name: String, 
  nationality: Option[String], 
  email: Option[String], 
  gender: Option[String]
)

字符串
使用play 2.1.3,我尝试创建一个JSON,如下所示:

{"name": "Joe", "email": "[email protected]"}


对于一个对象:

val user = new User("Joe, None, Some("[email protected]"), Some("male"))


使用:

val myJson = Json.obj("name" -> user.name, 
    "nationality" -> user.nationality, "email" -> user.email)


但我得到:

{"name": "Joe", "nationality": null, "email": "[email protected]"}


如何避免JSON中国籍为空值?

7gs2gvoe

7gs2gvoe1#

在意识到问题与播放JSON处理有关后,我设法找到了一个受I need advice on Play's Json and elegant Option handling in the Writes trait启发的解决方案。我不相信这是最优雅的解决方案,但它确实有效:

def writes(person: Person): JsValue = {
  JsObject(
    Seq[(String, JsValue)]() ++
    Some(person.name).map("name" -> JsString(_)) ++
    person.email.map("email" -> JsString(_))
  )
}

字符串

ztmd8pv5

ztmd8pv52#

我知道这是一个非常晚的响应,它不适用于原来的上下文中,但它可能是有用的今天。我有这个工作在Scala 3.3.1和Play 3.0:

implicit val personWrites: Writes[Person] = new Writes[Person] {

  def writes(o: StudentMarkRow): JsValue =
    val builder = Json.newBuilder
    builder += "name" -> o.name
    if o.nationality.isDefined then builder += "nationality" -> o.nationality.get
    if o.email.isDefined then builder += "email" -> o.email.get
    if o.gender.isDefined then builder += "gender" -> o.gender.get
    builder.result() 
}

字符串
可以抽象出模式if o.gender.isDefined then builder += "gender" -> o.gender.get,作为Builder trait的扩展方法。

相关问题