Scala:使用org.fastxml.jackson库

时间:2015-05-18 04:48:56

标签: json scala

我编写了以下程序来以流方式解析JSON结构。

然而,这看起来非常迫切。这是我最近尝试编写更多惯用的Scala代码,但我还没有。

我正在使用JSON片段后面的Scala代码解析以下JSON。我的目标是通过使用更多惯用的scala结构来缩短代码。 提前谢谢。

{
    "type": "ImportantIncidentInfo",
    "incidentTimestamp": "2014-05-15T10:09:27.989-05:00",
    "numOfMatches": 4,
    "myReport": {
        "docReports": {
            "part1/.": {
                "path": [
                    "unknown"
                ],
                "myAnalysis": {
                    "matches": [
                        {
                            "id": {
                                "major": 1,
                                "minor": 0
                            },
                            "name": "US SSN",
                            "position": 13,
                            "string": " 636-12-4567 "
                        },
                        {
                            "id": {
                                "major": 3,
                                "minor": 0
                            },
                            "name": "MasterCard Credit Card Number",
                            "position": 35,
                            "string": " 5424-1813-6924-3685 "
                        }
                    ]
                },
                "cleanedUpData": [
                    {
                        "startPosition": 0,
                        "endPosition": 65,
                        "frameContent": ""
                    }
                ],
                "minedMetadata": {
                    "Content-Encoding": "ISO-8859-1",
                    "Content-Type": "text/html; charset=iso-8859-1"
                },
                "deducedMetadata": {
                    "Content-Type": "text/html; iso-8859-1"
                }
            },
            "part2/.": {
                "path": [
                    "unknown"
                ],
                "myAnalysis": {
                    "matches": [
                        {
                            "id": {
                                "major": 1,
                                "minor": 0
                            },
                            "name": "SSN",
                            "position": 3,
                            "string": " 636-12-4567\r"
                        },
                        {
                            "id": {
                                "major": 3,
                                "minor": 0
                            },
                            "name": "MasterCard Credit Card Number",
                            "position": 18,
                            "string": "\n5424-1813-6924-3685\r"
                        }
                    ]
                },
                "cleanedUpData": [
                    {
                        "startPosition": 0,
                        "endPosition": 44,
                        "frameContent": ""
                    }
                ],
                "minedMetadata": {
                    "Content-Encoding": "windows-1252",
                    "Content-Type": "text/plain; charset=windows-1252"
                },
                "deducedMetadata": {
                    "Content-Type": "text/plain; iso-8859-1"
                }
            }
        }
    },
    "whatSetItOffEntry": {
        "action": "Log",
        "component": {
            "type": "aComponent",
            "components": [
                {
                    "type": "PatternComponent",
                    "patterns": [
                        1
                    ],
                    "not": false
                }
            ],
            "not": false
        },
        "ticketInfo": {
            "createIncident": true,
            "tags": [],
            "seeRestrictedIds": [
                {
                    "type": "userGroup",
                    "name": "SiteMasters",
                    "description": "Group for SiteMasters",
                    "masters": [
                        "04fb02a2bc0fba"
                    ],
                    "members": [],
                    "id": "04fade"
                }
            ]
        },
        "letmeknowInfo": {
            "createNotification": true,
            "contactNames": [
                "someguy@gmail.com"
            ]
        }
    },
    "seeRestrictedIds": [
        "04fade66c0"
    ],
    "status": "New",
    "timeStamps": [
        "2015-05-15T10:09:27.989-05:00"
    ],
    "count": 1
}

打包mypackage     import java.io.BufferedReader     import java.io.FileReader     import java.io.IOException     import java.io.InputStream     import java.util._     import com.fasterxml.jackson.core._     import com.fasterxml.jackson.databind._     import java.util.Properties     导入JacksonStreaming ._

object JacksonStreaming {

  def main(args: Array[String]) {
    println("Entered Main")
    try {
      new JacksonStreaming().getNames
    } catch {
      case e: Exception => e.printStackTrace()
    }
  }
}

class JacksonStreaming {

  var jsonMapper: ObjectMapper = new ObjectMapper()

  var jsonFactory: JsonFactory = new JsonFactory()

  var prop: Properties = new Properties()

  var filePath: String = ""

  val path = Array("myReport", "docReports", "part1/.", "myAnalysis", "matches", "name")

  def getNames() {
    println("Entered getNames")
    var rootNode: JsonNode = null
    try {
      val fileReader = new BufferedReader(new FileReader("C:/jsonFormattedModified.json"))
      println("fileReader is: " + fileReader)
      rootNode = jsonMapper.readTree(fileReader)
      println("Return value of jsonMapper.readTree is: " + rootNode)
      findByPath(rootNode)
      val jsonParser = jsonFactory.createParser(new FileReader("C:/jsonFormattedModified.json"))
      println("JsonParser is: " + jsonParser)
      var pathIndex = 0
      val names = new ArrayList[String]()
      var breakOnClose = false
      while (jsonParser.nextToken() != null) {
        val fieldName = jsonParser.getCurrentName
        if (fieldName == null) {
          //continue
        }
        if (breakOnClose && fieldName == path(path.length - 2)) {
          println("Stopping search at end of node " + fieldName)
          //break
        }
        if (jsonParser.getCurrentToken != JsonToken.FIELD_NAME) {
          //continue
        }
        if (pathIndex >= path.length - 1) {
          if (fieldName == path(path.length - 1)) {
            try {
              jsonParser.nextToken()
            } catch {
              case e: IOException => e.printStackTrace()
            }
            var name: String = null
            name = jsonParser.getValueAsString
            if (name == null) {
              throw new RuntimeException("No value exists for field " + fieldName)
            }
            names.add(name)
            println("Found " + fieldName + " value: " + name)
          }
        } else if (fieldName == path(pathIndex)) {
          println("Found node " + path(pathIndex))
          pathIndex += 1
          if (pathIndex >= path.length - 1) {
            println("Looking for names ...")
            breakOnClose = true
            try {
              jsonParser.nextFieldName()
            } catch {
              case e: IOException => e.printStackTrace()
            }
          }
        }
      }
    } catch {
      case e: IOException => e.printStackTrace()
    }
  }

  def findByPath(jn: JsonNode) {
    println("Entered findByPath")
    var matchesNamesNode = jn
    for (i <- 0 until path.length - 1) {
      matchesNamesNode = matchesNamesNode.path(path(i))
    }
    if (matchesNamesNode.isMissingNode) {
      throw new RuntimeException("No node with names found.")
    }
    println("Tree names: " + matchesNamesNode.findValuesAsText("name"))
  }
}

1 个答案:

答案 0 :(得分:0)

我认为Scala是面向表达式,面向对象和函数式编程语言,当然你可以写它必不可少但是为了使用JSON我推荐你去面向对象,你可以找到它的例子github repository

https://github.com/FasterXML/jackson-module-scala/

例如,我建议您编写A Scala,为All the Json编写类,然后为子对象(如MyReport或whatSetItOffEntry)编写,github repo是repo中此类解决方案的示例:

package com.fasterxml.jackson.module.scala

import com.fasterxml.jackson.annotation.{JsonUnwrapped, JsonProperty, JsonIgnore}
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import org.scalatest.matchers.ShouldMatchers
import org.scalatest.FlatSpec
import com.fasterxml.jackson.databind.ObjectMapper


case class Address(address1: Option[String], city: Option[String], state: Option[String])

class NonCreatorPerson
{
  var name: String = _
  @JsonUnwrapped var location: Address = _
  var alias: Option[String] = _
}

case class Person(name: String, @JsonIgnore location: Address, alias: Option[String])
{
  private def this() = this("", Address(None, None, None), None)

  def address1 = location.address1
  private def address1_=(value: Option[String]) {
    setAddressField("address1", value)
  }

  def city = location.city
  private def city_=(value: Option[String]) {
    setAddressField("city", value)
  }

  def state = location.state
  private def state_= (value: Option[String]) {
    setAddressField("state", value)
  }

  private def setAddressField(name: String, value: Option[String])
  {
    val f = location.getClass.getDeclaredField(name)
    f.setAccessible(true)
    f.set(location, value)
  }
}

@RunWith(classOf[JUnitRunner])
class UnwrappedTest extends BaseSpec {

  "mapper" should "handle ignored fields correctly" in {
    val mapper = new ObjectMapper()
    mapper.registerModule(DefaultScalaModule)

    val p = Person("Snoopy", Address(Some("123 Main St"), Some("Anytown"), Some("WA")), Some("Joe Cool"))
    val json = mapper.writeValueAsString(p)

    // There's some instability in the ordering of keys. Not sure what that's about, but rather than
    // have buggy tests, I'm accepting it for now.
    //    json should (
    //      be === """{"name":"Snoopy","alias":"Joe Cool","city":"Anytown","address1":"123 Main St","state":"WA"}""" or
    //      be === """{"name":"Snoopy","alias":"Joe Cool","state":"WA","address1":"123 Main St","city":"Anytown"}"""
    //    )

    val p2 = mapper.readValue(json, classOf[Person])

    p2 shouldEqual p
  }

  it should "handle JsonUnwrapped for non-creators" in {
    val mapper = new ObjectMapper()
    mapper.registerModule(DefaultScalaModule)

    val p = new NonCreatorPerson
    p.name = "Snoopy"
    p.location = Address(Some("123 Main St"), Some("Anytown"), Some("WA"))
    p.alias = Some("Joe Cool")

    val json = mapper.writeValueAsString(p)
    val p2 = mapper.readValue(json, classOf[NonCreatorPerson])

    p2.name shouldBe p.name
    p2.location shouldBe p.location
    p2.alias shouldBe p.alias
  }
}