jsonter, plokhotnyuk 如何使用地图将 json 解析为大小写 class
How to parse json to case class with map by jsonter, plokhotnyuk
我想从 Kafka 读取 json 消息并将它们放入 SpecificRecordBase class (avro) 的另一个结构中。 json 的部分具有动态结构,例如
{"known_type": "test",
"unknown_type": {"attr1": true, "attr2": "value2", "attr3": 777}}
{"known_type": "test",
"unknown_type": {"field1":[1,3,4,7], "field2": {"sub_field": "test"}}}
{"known_type": "test",
"unknown_type": {"param": "some_value"}}
我想使用灵活的 table 并将其放在 Map[String, String] 中,其中每个键 = 属性名称,值 = 字符串中的属性值,并且没有验证。目标示例 classes 实例:
Example(test,Map(attr1 -> true, attr2 -> "value2", attr3 -> 777))
Example(test,Map(field1 -> [1,3,4,7], field2 -> {"sub_field" : "sub_value"}))
Example(test,Map(param -> "some_value"))
我写的代码有一个圆圈,但想得到与plokhotnyuk/jsoniter-scala一样的代码,你能帮我找到方法吗
case class Example(known_type: String = "", unknown_type: Map[String, String])
val result: Option[Example] = for {
json <- parse(rawJson2).toOption
t <- json.hcursor.downField("known_type").as[String].toOption
map <- json.hcursor.downField("unknown_type").as[JsonObject].toOption
m = map.toMap.map { case (name, value) => name -> value.toString() }
} yield Example(t, m)
提出的通过问题解码测试的数据结构的可能解决方案之一:
case class Example(known_type: String = "", unknown_type: Map[String, String])
implicit val mapCodec: JsonValueCodec[Map[String, String]] = new JsonValueCodec[Map[String, String]] {
override def decodeValue(in: JsonReader, default: Map[String, String]): Map[String, String] = {
val b = in.nextToken()
if (b == '{') {
if (in.isNextToken('}')) nullValue
else {
in.rollbackToken()
var i = 0
val x = Map.newBuilder[String, String]
while ({
i += 1
if (i > 1000) in.decodeError("too many keys") // To save from DoS attacks that exploit Scala's map vulnerability: https://github.com/scala/bug/issues/11203
x += ((in.readKeyAsString(), new String({
in.nextToken()
in.rollbackToken()
in.readRawValAsBytes()
}, StandardCharsets.UTF_8)))
in.isNextToken(',')
}) ()
if (in.isCurrentToken('}')) x.result()
else in.objectEndOrCommaError()
}
} else in.readNullOrTokenError(default, '{')
}
override def encodeValue(x: Map[String, String], out: JsonWriter): Unit = ???
override val nullValue: Map[String, String] = Map.empty
}
implicit val exampleCodec: JsonValueCodec[Example] = make
我想从 Kafka 读取 json 消息并将它们放入 SpecificRecordBase class (avro) 的另一个结构中。 json 的部分具有动态结构,例如
{"known_type": "test",
"unknown_type": {"attr1": true, "attr2": "value2", "attr3": 777}}
{"known_type": "test",
"unknown_type": {"field1":[1,3,4,7], "field2": {"sub_field": "test"}}}
{"known_type": "test",
"unknown_type": {"param": "some_value"}}
我想使用灵活的 table 并将其放在 Map[String, String] 中,其中每个键 = 属性名称,值 = 字符串中的属性值,并且没有验证。目标示例 classes 实例:
Example(test,Map(attr1 -> true, attr2 -> "value2", attr3 -> 777))
Example(test,Map(field1 -> [1,3,4,7], field2 -> {"sub_field" : "sub_value"}))
Example(test,Map(param -> "some_value"))
我写的代码有一个圆圈,但想得到与plokhotnyuk/jsoniter-scala一样的代码,你能帮我找到方法吗
case class Example(known_type: String = "", unknown_type: Map[String, String])
val result: Option[Example] = for {
json <- parse(rawJson2).toOption
t <- json.hcursor.downField("known_type").as[String].toOption
map <- json.hcursor.downField("unknown_type").as[JsonObject].toOption
m = map.toMap.map { case (name, value) => name -> value.toString() }
} yield Example(t, m)
提出的通过问题解码测试的数据结构的可能解决方案之一:
case class Example(known_type: String = "", unknown_type: Map[String, String])
implicit val mapCodec: JsonValueCodec[Map[String, String]] = new JsonValueCodec[Map[String, String]] {
override def decodeValue(in: JsonReader, default: Map[String, String]): Map[String, String] = {
val b = in.nextToken()
if (b == '{') {
if (in.isNextToken('}')) nullValue
else {
in.rollbackToken()
var i = 0
val x = Map.newBuilder[String, String]
while ({
i += 1
if (i > 1000) in.decodeError("too many keys") // To save from DoS attacks that exploit Scala's map vulnerability: https://github.com/scala/bug/issues/11203
x += ((in.readKeyAsString(), new String({
in.nextToken()
in.rollbackToken()
in.readRawValAsBytes()
}, StandardCharsets.UTF_8)))
in.isNextToken(',')
}) ()
if (in.isCurrentToken('}')) x.result()
else in.objectEndOrCommaError()
}
} else in.readNullOrTokenError(default, '{')
}
override def encodeValue(x: Map[String, String], out: JsonWriter): Unit = ???
override val nullValue: Map[String, String] = Map.empty
}
implicit val exampleCodec: JsonValueCodec[Example] = make