如何在Scala中以字符串形式读取嵌套json对象的一部分 [英] How to read part of a nested json object in as a string in Scala

查看:40
本文介绍了如何在Scala中以字符串形式读取嵌套json对象的一部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将json对象读入scala类,该类将json对象的一部分保留为字符串,而不尝试解析它.

I want to read in a json object into a scala class that keeps part of the json object as a string without trying to parse it.

这是json的样子:

[
  {
    "contractType": "NullContract",
    "contractDefinition": {
      "column": "age",
      "conditions": [
        {
          "conditionType": "equalsCondition",
          "conditionDefinition": {
            "column": "species",
            "value": "person"
          }
        }
      ]
    }
  }
]

我正在使用杰克逊图书馆.这是我的映射器:

I am using the jackson library. This is my mapper:

val mapper = new ObjectMapper()
    .registerModule(DefaultScalaModule)
    .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
    .setSerializationInclusion(Include.NON_ABSENT)

这是我的课程:

case class ContractJson(contractType: String, contractDefinition: String)

,这就是我希望得到的对象看起来的样子.

, which is how I want my resulting object to look.

这是解析它的代码:

val contractJson: Array[ContractJson] = mapper.readValue(contractsJsonString, classOf[Array[ContractJson]])

我收到的错误消息:当开始解析 contractDefinition

推荐答案

如果允许您使用其他库,并且 contractDefinition 字段的类型不限于 String 然后尝试 jsoniter-scala的功能,将原始JSON值提取到字节数组.

If you are allowed to use other libraries and type of the contractDefinition field is not restricted to String then try jsoniter-scala's feature of extraction raw JSON values to byte arrays.

您将需要添加依赖项:

libraryDependencies ++= Seq(
  "com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-core"   % "1.1.0" % Compile,
  "com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-macros" % "1.1.0" % Provided // required only in compile-time
)

然后使用编解码器定义类型并解析输入:

Then define types with codecs and parse the input:

import java.nio.charset.StandardCharsets.UTF_8

import com.github.plokhotnyuk.jsoniter_scala.macros._
import com.github.plokhotnyuk.jsoniter_scala.core._

import scala.util.hashing.MurmurHash3

object RawVal {
  def apply(s: String) = new RawVal(s.getBytes)

  implicit val codec: JsonValueCodec[RawVal] = new JsonValueCodec[RawVal] {
    override def decodeValue(in: JsonReader, default: RawVal): RawVal = new RawVal(in.readRawValAsBytes())

    override def encodeValue(x: RawVal, out: JsonWriter): Unit = out.writeRawVal(x.bs)

    override val nullValue: RawVal = new RawVal(new Array[Byte](0))
  }
}

case class RawVal private(bs: Array[Byte]) {
  def this(s: String) = this(s.getBytes(UTF_8))

  override lazy val hashCode: Int = MurmurHash3.arrayHash(bs)

  override def equals(obj: Any): Boolean = obj match {
    case that: RawVal => java.util.Arrays.equals(bs, that.bs)
    case _ => false
  }

  override def toString: String = new String(bs, UTF_8)
}

case class ContractJson(contractType: String, contractDefinition: RawVal)

implicit val codec: JsonValueCodec[List[ContractJson]] = JsonCodecMaker.make(CodecMakerConfig)

val jsonBytes =
  """[
    |  {
    |    "contractType": "NullContract",
    |    "contractDefinition": {
    |      "column": "age",
    |      "conditions": [
    |        {
    |          "conditionType": "equalsCondition",
    |          "conditionDefinition": {
    |            "column": "species",
    |            "value": "person"
    |          }
    |        }
    |      ]
    |    }
    |  }
    |]
    |""".stripMargin.getBytes("UTF-8")

val contractJsons = readFromArray(jsonBytes)

println(contractJsons)

打印结果将是:

List(ContractJson(NullContract, {
  "column": "age",
  "conditions": [
    {
      "conditionType": "equalsCondition",
      "conditionDefinition": {
        "column": "species",
        "value": "person"
      }
    }
  ]
}))

这篇关于如何在Scala中以字符串形式读取嵌套json对象的一部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆