2015-09-07 117 views
0

的Scala的列表我代表一個星期的數據與具有天DATAS與其他相關參數影響周DATAS的列表的情況下的類:驗證JSON數組到特定長度

case class WeeksData (
    data: List[DaysData], 
    otherStuffRelatedToWeeksParameters: ... 
) 
case class DaysData (
    stuff: ... 
) 

我需要驗證輸入來自客戶端的Json,以便WeeksData數據參數恰好具有7個元素。你會如何建議我這樣做?

到目前爲止,我有

val weeksDataValidator: Reads[List[DaysData]] = ??? 
implicit val weeksDataWrites = Json.writes[WeeksData] 
implicit val weeksDataReads: Reads[WeeksData] = (
    (JsPath \ "weeksData").read[List[DaysData]](weeksDataValidator))(WeeksData.apply _) 

我知道我可以詮釋寫:

val intValidator: Reads[Int] = min(0) keepAnd max(999) 

那麼,如何寫一個驗證器的陣列/列表中,以便需要的長度是固定的(在這種情況下是7)?

或者我應該只需修改WeeksData類如

case class WeeksData (
    mon: DaysData, 
    tue: DaysData, 
    wed: DaysData, 
    ... 
    otherStuffRelatedToWeeksParameters: ... 
) 

由於

回答

0

模型被簡化爲短示例的目的:

case class A(weeks: List[Int]) 

def listReads[T](length: Int)(implicit anyListReads: Reads[List[T]]) = Reads[List[T]] { js => 
    anyListReads.reads(js).filter(JsError(ValidationError(s"Length of the list must be $length")))(_.size == length) 
} 

implicit val reads: Reads[A] = ((JsPath \ "weeks").read[List[Int]](listReads[Int](2))).map(A.apply _) 

使用(從REPL):

scala> Json.parse("""{ "weeks": [1, 2] }""").validate[A] 
res1: play.api.libs.json.JsResult[A] = JsSuccess(A(List(1, 2)),/weeks) 

scala> Json.parse("""{ "weeks": [1] }""").validate[A] 
res2: play.api.libs.json.JsResult[A] = JsError(List((/weeks,List(ValidationError(List(error.minLength),WrappedArray(2)))))) 
+0

謝謝!得到它的工作。結束了,因爲我想有固定的長度(不只是minimun): '.filterNot(ValidationError(s「列表的長度必須是$ length」))(_。length!= length)' – Alakiikonen

+0

啊,對不起,請稍後再編輯這篇文章。在查看默認的Play minLength讀取器後,我混淆了您的要求:) – Tyth

+0

Play 2.4.x上的小更新: '''.filterNot(JsError(s「列表的長度必須是$ length」))(_。length! = length)''' 作爲'''.filterNot(ValidationError)'''被分解 – Alakiikonen