簡體   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