【问题标题】:Extract nested entities and values from JSON从 JSON 中提取嵌套实体和值
【发布时间】:2014-08-20 02:06:42
【问题描述】:

我正在尝试从 Jira 中提取问题并将它们放入 List[Issue]。 我想出了如何下载和解析 JSON:

val json = JsonParser.parse(content)

我还可以在 JSON 的根目录中提取一些数字:

val total = (json \ "total").extract[Int]
val maxResults = (json \ "maxResults").extract[Int]
println("Received " + total + " from " + maxResults + " issues")

但是当我试图提取所有问题的列表时

val issues = (json \ "issues")
println(issues)
issues.extract[List[Issue]]

我收到一个错误: 线程“主”net.liftweb.json.MappingException 中的异常:id 没有可用值 不知道如何将 JString(13604) 转换为 int 我不明白为什么它不能将 13604 转换为 Int。 这是我的案例类:

case class Issue(id: Int,
    key: String,
    summary: String,
    issueTypeName: String,
    resolutionName: Option[String],
    resolutionDate: Option[DateTime],
    timeSpent: Option[Int],
    creatorName: String,
    reporterName: String,
    updated: DateTime,
    created: DateTime,
    priorityName: String,
    description: String,
    dueDate: Option[DateTime],
    statusName: String,
    assigneeName: String,
    projectId: Int,
    projectKey: String,
    projectName: String,
    timeEstimate: Option[Int],
    ownerName: String,
    timeOriginalEstimate: Option[Int]
                    )
  1. 有人可以帮我解决这个 Int 问题吗?

  2. 此外,JSON 为某些属性提供了嵌套元素,例如项目具有嵌套的 id、key 和 name。在我提取 json \ "issues" 的问题之前,我看到了另一个错误 - 我相信这是因为 JSON 提取器不知道他需要转到嵌套元素。 我怎么能让他知道呢? 我以为我可以这样做:

    for(问题

并将issue \ "project" \ "id" 用于嵌套项,然后创建新的Case Class 对象并将其添加到List var(可变但我不知道如何以其他方式进行)。但我收到编译时错误:

 Error:(53, 16) value foreach is not a member of net.liftweb.json.JsonAST.JValue
        for(issue <- issues) {
                     ^

我是 Scala 和整个 Java 基础架构和框架的新手,因此我希望提供代码示例。


PS。当我在案例类中将 id 更改为 String 时,我现在收到另一个错误:

Exception in thread "main" net.liftweb.json.MappingException: No usable value for summary Did not find value which can be converted into java.lang.String

这是因为“摘要”嵌套在“字段”中。所以,我的第二个问题仍然是实际的: 2. 如何处理嵌套值?

和新的相关问题: 3. 如果我想使用 Int 作为 id - 我该如何转换它?

【问题讨论】:

    标签: json scala jira lift case-class


    【解决方案1】:

    这是因为 json 中的 id 字段以字符串形式出现(“id”:“10230”https://developer.atlassian.com/display/JIRADEV/JIRA+REST+API+Example+-+Query+issues),liftjson 会自动转换为 JString。在您的案例类中,您需要将 id 字段设为字符串。

    2) 用例类来处理嵌套的 json。如果你有一个看起来像这样的 json

    {
      "id": "10230",
      "fields": {
        "summary": "testing"
      }
    }
    

    你需要两个案例类

    case class Issues(
       id: String,
       fields: Summary
    )
    
    case class Summary(
       summary: String
    )
    

    3) 我认为您不能在 extract 方法中转换为 Int,因为 JSON 结构将其定义为字符串。转换必须在您提取价值后发生。

    【讨论】:

    • 感谢您的回答 - 它很有帮助。但是现在我收到一个错误:线程“main”中的异常 net.liftweb.json.MappingException: No usable value for summary 没有找到可以转换为 java.lang.String 的值 - 这是因为“summary”嵌套在田野”。 1. 如何使用嵌套值? 2. 如果我需要使用 Int 作为 id - 我该如何转换它?
    • @KonstantinTrunin 您是否为您在上面的评论中提到的问题找到了解决方案? TIA
    【解决方案2】:

    我自己找到了解决方案:

    val issues = (json \\ "issues").children
     for (issue <- issues) {
            val item = new Issue (
                        (issue \ "id").extract[String].toInt,
                        (issue \ "fields" \ "summary").extract[String],
                        (issue \ "fields" \ "issuetype" \ "name").extract[String],
                        (issue \ "fields" \ "resolutiondate").extractOrNone[String] match {
                            case None => None
                            case Some (null) => None
                            case Some (dt) => Some (dateTimeFormatter.withZoneUTC ().parseDateTime (dt))
                        },
            etc...) 
    }
    

    在这种情况下,我继续使用单例类(我为自己的需要定义的结构)并将嵌套的 json 属性解析到其中,在需要的地方进行类型转换。

    【讨论】:

      猜你喜欢
      • 2014-05-16
      • 1970-01-01
      • 1970-01-01
      • 2015-07-24
      • 2021-08-26
      • 1970-01-01
      • 2023-03-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多