我有一个复杂的 JSON,它保存在数据库中。它的复杂性被“隔离”在“块”中,如下所示:
整个 JSON:
{
"block1" : {
"param1" : "val1",
"param2" : "val2"
},
"block2" : {
"param3" : "val3",
"param4" : "val4"
},
...
}
在数据库中,每个块都被单独存储和处理:
持久块
"block1" : {
"param1" : "val1",
"param2" : "val2"
}
"block2" : {
"param3" : "val3",
"param4" : "val4"
}
每个块都有业务意义,因此,每个块都映射到一个案例类。我正在构建一个存储、更新和检索此 JSON 结构的 Play API,并且我想验证是否有人为了完整性而更改了它的数据。
我正在对每个块进行检索(解析和验证),如下所示:
val block1 = Json.parse(block1).validate[Block1].get
val block2 = Json.parse(block2).validate[Block2].get
...
案例类:
trait Block
sealed case class Block1 (param1: String, param2: String, ...) extends Block
sealed case class Block2 (param3: String, param4: String, ...) extends Block
sealed case class Request (block1: Block1, block2: Block2, ...)
使用当前结构,如果某些字段被更改并且与它定义的类型不匹配,Play 会抛出此异常:
[NoSuchElementException:JsError.get]
因此,我想使用 Scalaz 和 Validation 构建一个累积错误结构,以捕获所有可能的解析和验证错误。我已经看到了这个和这个,所以我以这种方式对验证进行了编码:
def build(block1: String, block2: String, ...): Validation[NonEmptyList[String], Request] = {
val block1 = Option(Json.parse(block1).validate[Block1].get).toSuccess("Error").toValidationNel
val block2 = Option(Json.parse(block2).validate[Block2].get).toSuccess("Error").toValidationNel
...
val request = (Request.apply _).curried
blockn <*> (... <*> (... <*> (...<*> (block2 <*> (block1 map request)))))
}
请注意,我使用的是应用函子<*>
,因为Request
有 20 个字段(使用该语法构建括号混乱),|@|
应用函子仅适用于最多 12 个参数的案例类。
该代码适用于快乐路径,但是,当我修改某些字段时,Play 会引发稍后描述的执行异常。
问题:我想累积 Play 在解析每个块时可以检测到的所有可能的结构错误。我怎样才能做到这一点?
注意:如果在某种程度上Shapeless与此有关,我愿意使用它(我已经在使用它)。