2013-12-09 40 views
4

我在Scala中使用Playframework 2.2.1,並且正在編寫一個REST API,用戶可以在其中設置部分非結構化數據。基本上,用戶將發佈JSON看起來是這樣的:Playframework:如何將JSON綁定到包含地圖的案例類?

{ 
    "id": 1, 
    "name": "MyObject", 
    "properties": [ 
    "myFirstProperty": "Value 1", 
    "mySecondProperty": "Value 2" 
    ] 
} 

,我希望它綁定到一個案例類,看起來像:

case class Preference(id: Long, name: String, properties: Map[String, String]) 

我希望藉此劇的形式API的優勢爲此,我可以免費獲得一堆很好的驗證選項,但是我一直無法找到一種簡單的方法來實現這一點。理想的情況下(在我的腦海裏至少),我將能夠沿線的定義表單對象:

Form(
    mapping(
    "id" -> longNumber, 
    "name" -> nonEmptyText(min = 5), 
    "properties" -> map(nonEmptyText, nonEmptyText) 
)(Preference.apply)(Preference.unapply) 
) 

不幸的是,「地圖(文本,文本)」是虛構的。有沒有人使用表單API對此進行了類似的綁定?如果是這樣,怎麼樣?如果沒有,我很好奇你用什麼來驗證。這一切是手工完成的嗎?

在此先感謝您的幫助!

+0

運氣好嗎? –

回答

1

據我所知,表單API和json支持並不是要混合在一起。但是這不應該成爲一個問題,因爲你可以通過表單或者json讀取完成幾乎所有的驗證。

import play.api.libs.json._ 
import play.api.libs.functional.syntax._ 
import play.api.libs.json.Reads._ 
import play.api.data.validation.ValidationError 

val nonEmptyKeyValueMapReads = 
    filter[Map[String, String]](ValidationError("error.invalid"))(properties => 
    properties.keys.find(_.size == 0).isEmpty && properties.values.find(_.size == 0).isEmpty) 

val preferencesReads = 
    ((__ \ 'id).read[Long] and 
    (__ \ 'name).read[String](minLength[String](5)) and 
    (__ \ 'properties).read[Map[String, String]](nonEmptyKeyValueMapReads))(Preferences) 

有幾種方法可以實現您的屬性,這是其中之一。定義讀取之後,您可以使用它來驗證您的數據,例如myJson.validate(preferencesReads)

2

也許我誤解了你的問題,但不是the reads macro做你想做的事?

import play.api.libs.json._ 
import play.api.libs.functional.syntax._ 

implicit val preferenceReads = Json.reads[Preference] 

隨着範圍內隱,你可以使用asasOptvalidate你的JSON值轉換爲Preference(見the Play ScalaJson docs)。

+0

嗨@Aaron - 我編輯了這個問題,使其更加清晰,因爲回想起來,我沒有寫得太好。我的問題是關於將JSON解析與Play的Forms API相結合,這使得基本驗證(例如字符串長度)變得非常簡單和優雅。 – Joe

相關問題