【问题标题】:play framework json reads from empty string to empty list播放框架json从空字符串读取到空列表
【发布时间】:2018-01-11 19:00:46
【问题描述】:

大家好,最近我在将 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 提供的文档,但找不到信息。谁能给点建议?

提前致谢。

【问题讨论】:

    标签: json scala playframework


    【解决方案1】:

    正如您所提到的,默认的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])
    }
    

    这里要注意的关键是用JsResultyield 提供的整个内容。这为我们提供了所有必要的检查(例如 name 字段存在并且是字符串,hobbies 字段存在)。

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

    【讨论】:

      【解决方案2】:

      感谢@millhouse 的回答,它确实有效。就像他说的那样,我们需要一个自定义的Reads[Person] 来正确转换它。

      我还发布了我的代码作为参考。

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

      read[List[Hobby]].orElse(Reads.pure(List()))在值无法转换为List[Hobby]时会生成空列表。

      【讨论】:

        猜你喜欢
        • 2016-06-01
        • 2016-05-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-06
        • 2012-07-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多