繁体   English   中英

播放框架json从空字符串读取到空列表

[英]play framework json reads from empty string to empty list

大家好,最近我在将json转换为自己的数据模型时遇到了一个问题。

我有一个json格式的消息,其中可能包含一个空字符串:

{
    "name" : "John Doe", 
    "hobbies": ""
}

或爱好类型列表:

{
    "name" : "John Doe", 
    "hobbies": [{"name":"basketball"}]
}

以下是我在scala play框架中的案例类数据模型:

case class Person(name: String, hobbies: List[Hobby])
case class Hobby(name: String)

现在,我正在使用默认的json格式化程序,但是当我们将空字符串作为值时,它当然不能很好地工作。

implicit val HobbyJson= Json.format[Hobby]
implicit val PersonJson = Json.format[Person]

如果hobbies有一个空字符串,它将抛出异常。 当它为空字符串时,我想将其转换为空列表。 我搜索了Play提供的文档,但找不到信息。 任何人都可以提出建议吗?

提前致谢。

如前所述,默认的Format宏在这里对您不起作用,因为hobbies处理方式不一致。 因此,您需要实现自己的Reads[Person] -这是我的处理方式:

object PersonJson {
  implicit val hobbyConverter = Json.format[Hobby]

  val personReads = new Reads[Person] {

    override def reads(json: JsValue): JsResult[Person] = {
      for {
        personName  <- (json \ "name").validate[String]
        hobbies     <- (json \ "hobbies").validate[JsValue]
      } yield {
        val maybeHobbyList = hobbies.validate[List[Hobby]].asOpt
        Person(personName, maybeHobbyList.getOrElse(Nil))
      }
    }
  }

  implicit val personConverter = Format(personReads, Json.writes[Person])
}

这里要注意的关键是,出于理解和yield的考虑, JsResult中包含了整个内容。 这为我们提供了所有必要的检查(例如, name字段在那里并且是String,而hobbies字段在那里)。

仅当我们拥有看起来非常接近Person东西时, yield块中的代码才运行。 然后,我们可以安全地尝试将hobbies验证为List[Hobby] ,并将结果转换为Option[List[Hobby]] 如果不起作用,它将为None (因此它必须是字符串),因此我们根据需要将其默认为空列表。

谢谢@millhouse的回答,它肯定可以工作。 就像他说的那样,我们需要一个自定义的Reads[Person]来正确转换它。

我还将代码发布为参考。

  implicit val personJsonReads: Reads[Person] = (
      (__ \ "name").read[String] and
      (__ \ "hobbies").read[List[Hobby]].orElse(Reads.pure(List())) 
  ) (Person.apply _)

当值无法转换为List[Hobby]时, read[List[Hobby]].orElse(Reads.pure(List()))将生成一个空列表。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM