验证 JSON 架构运行时

Validation JSON schema runtime

我想避免运行时未定义的行为如下:

val jsonExample = Json.toJson(0)
jsonExample.asOpt[Instant]

产量Some(1970-01-01T00:00:00Z)

我如何使用带提升功能的部分函数或其他方式来验证它确实如此 Instant,或者您建议如何验证?

ex1:
val jsonExample = Json.toJson(Instant.now())
jsonExample match { ... }

ex2:
val jsonExample = Json.toJson(0)
jsonExample match { ... }

所需输出的示例:

validateInstant(Json.toJson(Instant.now())) -> return Some(...)
validateInstant(Json.toJson(0)) -> return None

我可以做以下事情,也许还有其他想法?

只是想添加一个关于解析 json 的注释,当我们尝试解析 .asOpt[T] 时出现了一些运行时未定义的问题 例如:

Json.toJson("0").asOpt[BigDecimal] // yields Some(0)
Json.toJson(0).asOpt[Instant] // yields Some(1970-01-01T00:00:00Z)
We can validate it as follows or some other way:
Json.toJson("0") match {
  case JsString(value) => Some(value)
  case _ => None
}

Json.toJson(0) match {
  case JsNumber(value) => Some(value)
  case _ => None
}

Json.toJson(Instant.now()) match {
  case o @ JsString(_) => o.asOpt[Instant]
  case _ => None
}

您可以使用选项:

def filterNumbers[T](value: T)(implicit tjs: Writes[T]): Option[Instant] = {
  Option(Json.toJson(value)).filter(_.asOpt[JsNumber].isEmpty).flatMap(_.asOpt[Instant])
}

然后是:

println(filterNumbers(Instant.now()))
println(filterNumbers(0))

将输出:

Some(2021-02-22T10:35:13.777Z)
None