【问题标题】:Scala - parse JSON data from API with ScalaJson Play FrameworkScala - 使用 ScalaJson Play 框架从 API 解析 JSON 数据
【发布时间】:2018-07-18 12:06:37
【问题描述】:

首先,我实现了一种从 csv 文件构建Map[Double, String] 的方法。该地图包含 saleId、saleType 的 (k,v)。 以下是我的实现方式:

val stream : InputStream = getClass.getResourceAsStream("/sales.csv")
  val lines: Iterator[String] = scala.io.Source.fromInputStream(stream).getLines
  val map: Map[Double, String] = lines
    .map(_.split(","))
    .map(line => (line(0).toDouble, line(1).toString))
    .toMap

现在我想更进一步,获取数据以使用来自 API 的数据构建地图。使用相同的 k,v (saleId, saleType)。 API 返回的 Json 包含此数据作为字段。

Json 看起来像这样:

   [{ 
    "saleId": 1234, 
    "name": "New name", 
    "saleType": "New Type"
    }, 
    { 
    "saleId": 2345, 
    "name": "New name1", 
    "saleType": "New Type1" 
   }]

所以我尝试了使用 ScalaJson Play Framework 的方法。由于我只需要 JSON 中的两个字段,因此我决定使用案例类 SalesData

object SalesProcessor {
    case class SalesData(saleId: Int, saleType: String)
    implicit val of: Reads[SalesData] = reads[SalesData]

      val rawJson: String = Source.fromURL("https://mytest.com/api/sales.json").mkString
      val salesJson: JsValue = Json.parse(rawJson)
      val salesData: SalesData = salesJson.as[SalesData]

    def main(args: Array[String]): Unit = {
        println(salesData.saleId)
    }

当我运行上述代码时,我收到以下错误:

play.api.libs.json.JsResultException: JsResultException(errors:List((,List(JsonValidationError(List(error.expected.jsobject),WrappedArray())))))

UPD:在我使用了 tea-addict 提出的解决方案后,它开始失败并出现以下错误:

JsResultException(errors:List((/saleId,List(JsonValidationError(List(error.path.missing),WrappedArray()))), (/saleType,List(JsonValidationError(List(error.path.missing),WrappedArray())))))

【问题讨论】:

  • 您能否展示sales.json 文件的样本
  • @Seraf 在帖子中添加了 Json 示例

标签: json scala playframework


【解决方案1】:

您可以读取特定字段并像这样创建您的SalesData

Sales.json

[{ 
  "saleId": 1234, 
  "name": "New name", 
  "saleType": "New Type"
}, 
{ 
  "saleId": 2345, 
  "name": "New name1", 
  "saleType": "New Type1" 
 }]

代码

object SalesProcessor {
    case class SalesData(saleId: Int, saleType: String)
    implicit val saleReads: Reads[SalesData] = (
        (JsPath \ "saleId").read[Int] and
        (JsPath \ "saleType").read[String]
    ) (SalesData.apply _)

    val rawJson: String = Source.fromURL("https://mytest.com/api/sales.json").mkString
    val salesJson: JsValue = Json.parse(rawJson)
    val salesData: List[SalesData] = salesJson.as[List[SalesData]]

    def main(args: Array[String]): Unit = {
        println(salesData(0).saleId)
    }
}

【讨论】:

  • 我只需要 json 文件中的两个字段:saleId 和 saleType。很抱歉弄错了json文件,它实际上和case类有相同的字段名
  • 仍然收到 JsResultException(errors:List((/saleId,List(JsonValidationError(List(error.path.missing),WrappedArray()))), (/saleType,List(JsonValidationError(List(error.path.missing),WrappedArray()))))) 。可能是由 json 结构(包装成数组的对象)引起的吗?我已经用 json 的有效示例更新了我的帖子
  • val salesData: List[SalesData] = salesJson.as[List[SalesData]]
  • 按照您上面的建议,我已更改为 List[SalesData]。并打电话给salesData.foreach(sale => println(sale.saleId + " " + sale.saleType))。现在得到 JsonValidationErrors: ((1234)/saleId,List(JsonValidationError(List(error.expected.jsnumber),WrappedArray()))), ((2345)/saleId,List(JsonValidationError(List(error.expected.jsnumber),WrappedArray()))) ..... etc
  • 非常感谢!您确实帮助我重新评估了我的解决方案并从不同的角度看待问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多