[英]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.