我的代碼包含以下物體:
case class Source(uuid: String, `type`: String, parameters: Connector)
sealed trait Connector
case class Snowflake(
val username: String,
val password: String,
val host: String,
val role: Option[String],
val warehouse: Option[String],
val port: Option[String],
val db_name: String,
val schema: Option[String],
val activeModal: Option[String],
val use_ssh: Int,
val ssh_ip: Option[String],
val ssh_port: Option[Int],
val ssh_user: Option[String]
) extends Connector {
val options = Map(
("sfURL" -> s"${host}.snowflakecomputing.com"),
("sfUser" -> username),
("sfPassword" -> password),
("sfRole" -> role),
("sfDatabase" -> db_name),
("sfSchema" -> schema),
("sfWarehouse" -> warehouse))
}
case class MySQL(
...
) extends Connector {
...
}
case class File(
...
) extends Connector {
...
}
我正在嘗試反序列化表示不同連接器型別的 json。Json 可以如下所示:
val test = {
"uuid":"12314sdfds12",
"type":"snowflake",
"parameters": "{\"use_ssh\": 0,
\"schema\": \"YESDATA\",
\"activeModal\": \"showflake\",
\"warehouse\": \"COMPUTE_WH\",
\"role\": \"DIsdfasROLE\",
\"username\": \"Dixcxf\",
\"password\": \"dfgRvf65&Vyuhj65&\",
\"host\": \"wn789454.east-us-2.azure\",
\"db_name\": \"DSPSHARE2\"}"
}
問題是“parameters”欄位是字串型別,json可以包含除uuid、型別和引數之外的更多欄位。我想出了 Source 類的自定義序列化程式:
case object SourceSerializer extends CustomSerializer[Source](format => (
{
case JObject(source) => {
implicit val formats: Formats = DefaultFormats
def getfield(key: String) = source.filter(field => field match {
case JField(`key`, JString(_)) => true
case _ => false
})
getfield("uuid") match {
case List(JField("uuid", JString(uuid))) => {
val JString(connectorType) = JObject(source) \ "type"
val JString(connectorParams) = JObject(source) \ "parameters"
connectorType match {
case "snowflake" => Source(uuid, connectorType, parse(connectorParams).extract[Snowflake])
}
}
case Nil => null
}}
case JNull => null
},
{ case op: Source => JString(op.getClass.getSimpleName.replace("$","")) }
))
最后,我嘗試像這樣使用它:
parse(test).extract[Source]
它失敗了,我收到了錯誤
[error] org.json4s.MappingException: Unexpected type info RefinedType(ClassSymbol(<refinement>, owner=0, flags=0, info=173 ,None),List(TypeRefType(ThisType(java.lang),java.lang.Object,List()), TypeRefType(ThisType(java.io),java.io.Serializable,List())))
[error] at org.json4s.reflect.package$.fail(package.scala:56)
[error] at org.json4s.reflect.ScalaSigReader$.findPrimitive$3(ScalaSigReader.scala:194)
[error] at org.json4s.reflect.ScalaSigReader$.findArgTypeForField(ScalaSigReader.scala:196)
[error] at org.json4s.reflect.ScalaSigReader$.readField(ScalaSigReader.scala:77)
[error] at org.json4s.reflect.Reflector$ClassDescriptorBuilder.$anonfun$fields$3(Reflector.scala:113)
[error] at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:238)
[error] at scala.collection.mutable.ResizableArray.foreach(ResizableArray.scala:62)
[error] at scala.collection.mutable.ResizableArray.foreach$(ResizableArray.scala:55)
[error] at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:49)
[error] at scala.collection.TraversableLike.map(TraversableLike.scala:238)
[error] at scala.collection.TraversableLike.map$(TraversableLike.scala:231)
[error] at scala.collection.AbstractTraversable.map(Traversable.scala:108)
[error] at org.json4s.reflect.Reflector$ClassDescriptorBuilder.fields(Reflector.scala:111)
[error] at org.json4s.reflect.Reflector$ClassDescriptorBuilder.properties(Reflector.scala:130)
[error] at org.json4s.reflect.Reflector$ClassDescriptorBuilder.result(Reflector.scala:272)
[error] at org.json4s.reflect.Reflector$.createDescriptorWithFormats(Reflector.scala:87)
[error] at org.json4s.reflect.Reflector$.$anonfun$describeWithFormats$1(Reflector.scala:70)
[error] at org.json4s.reflect.Memo.apply(Memo.scala:12)
[error] at org.json4s.reflect.Reflector$.describeWithFormats(Reflector.scala:70)
[error] at org.json4s.Extraction$.$anonfun$extract$10(Extraction.scala:456)
[error] at org.json4s.Extraction$.$anonfun$customOrElse$1(Extraction.scala:781)
[error] at scala.PartialFunction.applyOrElse(PartialFunction.scala:127)
[error] at scala.PartialFunction.applyOrElse$(PartialFunction.scala:126)
[error] at scala.PartialFunction$$anon$1.applyOrElse(PartialFunction.scala:257)
[error] at org.json4s.Extraction$.customOrElse(Extraction.scala:781)
[error] at org.json4s.Extraction$.extract(Extraction.scala:455)
[error] at org.json4s.Extraction$.extract(Extraction.scala:56)
[error] at org.json4s.ExtractableJsonAstNode$.extract$extension(ExtractableJsonAstNode.scala:22)
[error] at org.json4s.jackson.JacksonSerialization.read(Serialization.scala:62)
[error] at org.json4s.Serialization.read(Serialization.scala:31)
[error] at org.json4s.Serialization.read$(Serialization.scala:31)
[error] at org.json4s.jackson.JacksonSerialization.read(Serialization.scala:23)
[error] at org.divian.entities.ConnectorSerializer$$anonfun$$lessinit$greater$2$$anonfun$apply$3.applyOrElse(Entities.scala:236)
[error] at org.divian.entities.ConnectorSerializer$$anonfun$$lessinit$greater$2$$anonfun$apply$3.applyOrElse(Entities.scala:223)
[error] at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:38)
[error] at org.json4s.CustomSerializer$$anonfun$deserialize$1.applyOrElse(CustomSerializer.scala:11)
[error] at org.json4s.CustomSerializer$$anonfun$deserialize$1.applyOrElse(CustomSerializer.scala:10)
[error] at org.json4s.Extraction$.customOrElse(Extraction.scala:781)
[error] at org.json4s.Extraction$.extract(Extraction.scala:455)
[error] at org.json4s.Extraction$.extract(Extraction.scala:56)
[error] at org.json4s.ExtractableJsonAstNode$.extract$extension(ExtractableJsonAstNode.scala:22)
[error] at org.divian.entities.SourceSerializer$$anonfun$$lessinit$greater$3$$anonfun$apply$5.applyOrElse(Entities.scala:273)
[error] at org.divian.entities.SourceSerializer$$anonfun$$lessinit$greater$3$$anonfun$apply$5.applyOrElse(Entities.scala:251)
[error] at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:38)
[error] at org.json4s.CustomSerializer$$anonfun$deserialize$1.applyOrElse(CustomSerializer.scala:11)
[error] at org.json4s.CustomSerializer$$anonfun$deserialize$1.applyOrElse(CustomSerializer.scala:10)
[error] at org.json4s.Extraction$.customOrElse(Extraction.scala:781)
[error] at org.json4s.Extraction$.extract(Extraction.scala:455)
[error] at org.json4s.Extraction$.extract(Extraction.scala:56)
[error] at org.json4s.ExtractableJsonAstNode$.extract$extension(ExtractableJsonAstNode.scala:22)
[error] at Main$.delayedEndpoint$Main$1(main.scala:48)
[error] at Main$delayedInit$body.apply(main.scala:21)
[error] at scala.Function0.apply$mcV$sp(Function0.scala:39)
[error] at scala.Function0.apply$mcV$sp$(Function0.scala:39)
[error] at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:17)
[error] at scala.App.$anonfun$main$1$adapted(App.scala:80)
[error] at scala.collection.immutable.List.foreach(List.scala:392)
[error] at scala.App.main(App.scala:80)
[error] at scala.App.main$(App.scala:78)
[error] at Main$.main(main.scala:21)
[error] at Main.main(main.scala)
[error] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[error] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[error] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[error] at java.lang.reflect.Method.invoke(Method.java:498)
[error] stack trace is suppressed; run last Compile / run for the full output
[error] (Compile / run) org.json4s.MappingException: Unexpected type info RefinedType(ClassSymbol(<refinement>, owner=0, flags=0, info=173 ,None),List(TypeRefType(ThisType(java.lang),java.lang.Object,List()), TypeRefType(ThisType(java.io),java.io.Serializable,List())))
[error] Total time: 16 s, completed Jun 19, 2022 2:14:04 AM
我查了一下,那個:
- 當 Snowflake 沒有從 Connector 擴展時,一切正常:
val ctest = """{"use_ssh": 0, "schema": "YESDATA", "activeModal": "showflake", "warehouse": "COMPUTE_WH", "role": "DIv453SEFROLE", "username": "Disdfg324", "password": "Vgdtj65&stghj65&", "host": "wn354673.east-us-2.azure", "db_name": "DSPSHARE2"}""" parse(ctest).extract[Snowflake] /* prints correct instance of Snowflake */ - 我是用抽象類、密封特性還是特性來實作它都沒有關系。
- 我嘗試使用提示而不是連接器的自定義序列化程式 - 沒有成功。
- 嘗試使用不同版本的 json4s(以防萬一) - 沒有成功。
我將非常感謝任何建議。
uj5u.com熱心網友回復:
原來問題出在Snowflake. .getOrElse("")通過添加地圖的Option[]值解決了這個問題options:
case class Snowflake(
val username: String, //
val password: String, //
val host: String, //
val role: Option[String], //
val warehouse: Option[String], //
val port: Option[String], // String?
val db_name: String, //
val schema: Option[String], //
val activeModal: Option[String],
val use_ssh: Int, //
val ssh_ip: Option[String],
val ssh_port: Option[Int],
val ssh_user: Option[String]
) extends Connector {
val options = Map(
("sfURL" -> s"${host}.snowflakecomputing.com"),
("sfUser" -> username),
("sfPassword" -> password),
("sfDatabase" -> db_name),
("sfRole" -> role.getOrElse("")),
("sfSchema" -> schema.getOrElse("")),
("sfWarehouse" -> warehouse.getOrElse("")))
}
但是,這仍然是一個有趣的行為。我認為如果 json 中沒有值,Option[]建構式 val 正在獲取值。None因此,我認為創建具有None值的 Map 沒有問題。
例如,我可以創建這樣的東西:
val test = Map(
("key1" -> "stringValue"),
("key2" -> 123),
("key3" -> None)
)
這將是一個Map[String, Any]. 不明白為什么它會導致我的錯誤。
如果有人可以解釋-那就太好了。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/496952.html
