繁体   English   中英

如何在scala中解析json list或array for play framework 2.2

[英]How to parse json list or array in scala for play framework 2.2

我正在编写一些RESTful API测试用例,并且几乎没有使用scala playframwork的经验。

这是我的JSON的一个例子。

  [ {
   "size" : "5082",
   "date-created" : "Wed Nov 19 17:10:39 CST 2014",
   "id" : "546d236fb84e894eefd8f769",
   "content-type" : "image/png",
   "filename" : "chrome-on-windows.PNG"
 }, {
   "size" : "15684",
   "date-created" : "Mon Jan 12 17:28:02 CST 2015",
   "id" : "54b4588266b3d11b1c1e9db6",
   "content-type" : "image/png",
   "filename" : "logos_ncsa.png"
 }, {
   "size" : "1267871",
   "date-created" : "Mon Jan 12 17:28:03 CST 2015",
   "id" : "54b4588366b3d11b1c1e9dba",
   "content-type" : "image/jpg",
   "filename" : "morrowplots.jpg"
 } ]

如您所见,我有一个JSON项列表/数组。 我想获取“morrowplots.jpg”文件的id并将其存储到变量中以用于成功的API调用。

所以我将我的代码设置为如下所示。 下面代码中的结果变量是您在上面看到的JSON字符串。

  case class FileName(size: String, datecreated: String, id: String,    contenttype: String, filename: String)

  implicit val fileReads: Reads[FileName] = (
  (__ \\ "size").read[String] and
  (__ \\ "datecreated").read[String] and
  (__ \\ "id").read[String] and
  (__ \\ "content-type").read[String] and
  (__ \\ "filename").read[String]
  )(FileName.apply _)

  val json: JsValue = Json.parse(contentAsString(result))

  val nameResult: JsResult[FileName] = json.validate[FileName](fileReads)
  info("Right after validate")
    nameResult match {
      case s: JsSuccess[FileName] => {
        val testfile: FileName = s.get
        // Do something with testfile
        info("Success")
      }
      case e: JsError => {
        info("Error")
        info("Errors: " + JsError.toFlatJson(e).toString())
      }
    }

这给了我以下错误。

[info] +错误:{“obj size”:[{“msg”:“error.path.result.multiple”,“args”:[]}],“obj filename”:[{“msg”:“error .path.resul t.multiple“,”args“:[]}],”obj id“:[{”msg“:”error.path.result.multiple“,”args“:[]}],”obj content-type“:[{”msg“:”error.path .result.multiple“,”args“:[]}],”obj * datecreated“:[{”msg“:”error.path.missing“, “ARGS”:[]}]}

那么如何修复此List / Array问题以及如何通过filename搜索以获取ID?

提前致谢。

首先,您可能决定使用内置的json实用程序而不是执行手动解析。

  case class FileName(size: String, datecreated: String, id: String,    contenttype: String, filename: String)
  object FileName {
    implicit val formatFileName = Json.format[FileName]
  }

在那里,您拥有解析基本json对象所需的一切。 编译器将使用宏(IIRC)生成与您手动编写的代码等效的代码。 由于您的字段没有异常验证,因此无需手动编写Reads and Writes类。

然后你可以这样读它:

    def readString(str: String) = {
      val jsr: JsResult[Seq[FileName]] = Json.parse(str).validate[Seq[FileName]]
      jsr.fold(
        error => {
          ???
        },
        success => {
          ???
        }
      )
    }

jsr在这里是一个JsResult。 它可以是JsSuccess或JsError。

请注意完整类型。 由于您有一个数组作为输入,您应该将输出设置为一个集合,例如Seq。

你可以折叠你的JsResult。 fold需要两个功能。 一个是错误情况,它有类型Seq [(JsPath,Seq [ValidationError])] => X,其中X是函数的返回类型。 它向您显示阻止您的json转换为Seq [FileName]的所有问题。

另一个是成功案例。 它的类型为Seq [FileName] => X,与之前的X相同。

您现在可以决定在这两个函数中放入什么。

正如Justin所指出的,你也可以用匹配来写它。 它可能更容易,即使功能较少:

    def readString(str: String) = {
      val jsr: JsResult[Seq[FileName]] = Json.parse(str).validate[Seq[FileName]]
      jsr match {
        case JsResult(seq) => ???
        case e: JsError => ???
      }
    } 

我不是Play的专家,所以这可能不是惯用的,但它应该解决你的问题。 首先,你的json是date-created而你的scala期望是datecreated 其次,你应该只为你的Reads使用一个斜杠。 接下来,您需要对List[FileName]运行validate

至于文件名搜索,您现在可以从JsSuccess提取列表并对其运行filter

最终的代码看起来像这样

case class FileName(size: String, datecreated: String, id: String, contenttype: String, filename: String)

  implicit val fileReads: Reads[FileName] = (
  (__ \ "size").read[String] and
  (__ \ "date-created").read[String] and
  (__ \ "id").read[String] and
  (__ \ "content-type").read[String] and
  (__ \ "filename").read[String]
  )(FileName)

  val json: JsValue = Json.parse(contentAsString(result))

  val nameResult = json.validate[List[FileName]]

  val list = nameResult match {
      case JsSuccess(list : List[FileName], _) => list
      case e: JsError => {
        info("Errors: " + JsError.toFlatJson(e).toString())
        List()
      }
    }

  list filter(_.filename contains "morrow")

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM