【问题标题】:Play framework 2.5 reads optional filterPlay framework 2.5 读取可选过滤器
【发布时间】:2016-05-19 11:16:32
【问题描述】:

我有以下读取函数来解析 JSON 文件。

 case class tables(col1 : Option[List[another case class]], col2 : Option[List[another case class]], col3 : Option[List[another case class]], col4 : Option[List[another case class]])


implicit val tablesRead: Reads[tables] = (
        (JsPath \ "col1").read(Reads.optionWithNull[List[data1]]).filterNot(_.get.isEmpty) and
          (JsPath \ "col2").read(Reads.optionWithNull[List[data2]]).filterNot(_.get.isEmpty) and
          (JsPath \ "col3").read(Reads.optionWithNull[List[data3]]).filterNot(_.get.isEmpty) and
          (JsPath \ "col4").read(Reads.optionWithNull[List[data4]]).filterNot(_.get.isEmpty)
        ) (tables.apply _)

我想在验证后将 JSON 插入数据库。因此,我声明了以下函数。

def createFromJson = Action.async(parse.json) { request =>
    request.body.validate[jsonWrapper] match {
      case JsSuccess(data, _) =>
        for {
          dbFuture <- dataFuture(data.userID)
          lastError <- dbFuture.insert(data.tables)
        } yield {
         Ok("Success\n")
        }
      case JsError(errors) => Future.successful(BadRequest("Failed :" + Error.show(errors)))
    }
  }

这可以正常工作并正确拒绝如下所示的 JSON:

{"tables":{"col1":[],"col2":[],"col3":[],"col4":[]}, "userID":"irrelavent"}

并接受带有实际数据的 JSON,如下所示:

{"tables":{"col1":[{data1}],"col2":[{data2}],"col3":[{data3}],"col4":[{data4}]}, "userID":"irrelavent"}

但我需要的是能够做到这一点但也接受缺少字段的 JSON

{"tables":{"col1":[{data1}],"col2":[],"col3":[{data3}],"col4":[{data4}]}, "userID":"irrelavent"}

最好忽略它们(即返回类似: {"tables":{"col1":[{data1}],"col3":[{data3}],"col4":[{data4}]}, "userID":"irrelavent"})

这可能吗?

非常感谢,

彼得 M.

【问题讨论】:

  • 您的tables 班级是什么样的?为什么不直接使用Json.reads[tables] 而不是编写自己的阅读器?如果字段具有Option 类型,则Json.reads 宏生成的读取器会自动接受缺失的字段。
  • @dtech 我已经添加了我的表格案例类。读取来自 play.api.libs.json 包,所以,如果我没记错的话,我使用的是 Json.reads。相信我的案例类的每个成员都是一个选项,这导致了我遇到的问题。
  • 如果我理解正确,您希望验证并接受所有 col2 变体的 Json:1. 省略,2. 存在空数组,3. 存在填充数组?
  • 不,我想忽略所有空字段(例如 col1:[])并在验证键值时接受其他所有内容(这样我就不能包含任何随机键)。希望这是一个更清晰的解释。

标签: json scala playframework


【解决方案1】:

您可以使用 Json.reads 宏自动生成 Reads[tables] 并具有您想要的行为:

implicit val tablesRead: Reads[tables] = Json.reads[tables]

如果 JSON 中缺少字段,则该列将为 None

稍微注意一下,scala 中的常见形式是以大写字母开头的类名,因此您应该将 tables 重命名为 Tables

【讨论】:

  • 我不得不调整一下我的代码(我发送 JSON 的方式),但它现在可以工作了。谢谢,我记得从这样开始,并没有让它完全按照我想要的方式工作,最终导致事情变得复杂。并感谢您的班级名称规范,我总是忘记他们......
猜你喜欢
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 2017-09-14
  • 1970-01-01
  • 2018-07-31
  • 2016-08-28
  • 2016-07-14
  • 2017-03-28
相关资源
最近更新 更多