JSON4S型暗示不起作用
问题描述:
以下测试片段JSON4S型暗示不起作用
implicit val formats = DefaultFormats + FullTypeHints(Contacts.classList)
val serialized = Serialization.write(List(Mail(field = "[email protected]", note = "Random note.")))
println(serialized)
Serialization.read[List[Contact[_]]](serialized).isInstanceOf[List[Mail]] should be (true)
失败
Can't find constructor for Contact[Object]
org.json4s.package$MappingException: Can't find constructor for Contact[Object]
at org.json4s.reflect.package$.fail(package.scala:95)
at org.json4s.reflect.ScalaSigReader$$anonfun$5.apply(ScalaSigReader.scala:21)
at org.json4s.reflect.ScalaSigReader$$anonfun$5.apply(ScalaSigReader.scala:21)
at scala.Option.getOrElse(Option.scala:121)
at org.json4s.reflect.ScalaSigReader$.readConstructor(ScalaSigReader.scala:21)
at org.json4s.reflect.Reflector$ClassDescriptorBuilder.ctorParamType(Reflector.scala:93)
at org.json4s.reflect.Reflector$ClassDescriptorBuilder$$anonfun$createConstructorDescriptors$3$$anonfun$15.apply(Reflector.scala:156)
at org.json4s.reflect.Reflector$ClassDescriptorBuilder$$anonfun$createConstructorDescriptors$3$$anonfun$15.apply(Reflector.scala:142)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:234)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:234)
at scala.collection.mutable.ResizableArray$class.foreach(ResizableArray.scala:59)
at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:48)
at scala.collection.TraversableLike$class.map(TraversableLike.scala:234)
at scala.collection.AbstractTraversable.map(Traversable.scala:104)
at org.json4s.reflect.Reflector$ClassDescriptorBuilder$$anonfun$createConstructorDescriptors$3.apply(Reflector.scala:142)
at org.json4s.reflect.Reflector$ClassDescriptorBuilder$$anonfun$createConstructorDescriptors$3.apply(Reflector.scala:136)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:234)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:234)
at scala.collection.mutable.ArraySeq.foreach(ArraySeq.scala:74)
at scala.collection.TraversableLike$class.map(TraversableLike.scala:234)
at scala.collection.AbstractTraversable.map(Traversable.scala:104)
at org.json4s.reflect.Reflector$ClassDescriptorBuilder.createConstructorDescriptors(Reflector.scala:136)
at org.json4s.reflect.Reflector$ClassDescriptorBuilder.constructorsAndCompanion(Reflector.scala:121)
at org.json4s.reflect.Reflector$ClassDescriptorBuilder.result(Reflector.scala:183)
at org.json4s.reflect.Reflector$.createDescriptor(Reflector.scala:53)
at org.json4s.reflect.Reflector$$anonfun$describe$1.apply(Reflector.scala:48)
at org.json4s.reflect.Reflector$$anonfun$describe$1.apply(Reflector.scala:48)
at org.json4s.reflect.package$Memo.apply(package.scala:36)
at org.json4s.reflect.Reflector$.describe(Reflector.scala:48)
at org.json4s.Extraction$$anonfun$extract$6.apply(Extraction.scala:393)
at org.json4s.Extraction$$anonfun$extract$6.apply(Extraction.scala:392)
at org.json4s.Extraction$.customOrElse(Extraction.scala:606)
at org.json4s.Extraction$.extract(Extraction.scala:392)
at org.json4s.Extraction$CollectionBuilder$$anonfun$7.apply(Extraction.scala:410)
at org.json4s.Extraction$CollectionBuilder$$anonfun$7.apply(Extraction.scala:410)
at scala.collection.immutable.List.map(List.scala:284)
at org.json4s.Extraction$CollectionBuilder.mkCollection(Extraction.scala:410)
at org.json4s.Extraction$CollectionBuilder.result(Extraction.scala:430)
at org.json4s.Extraction$$anonfun$extract$5.apply(Extraction.scala:382)
at org.json4s.Extraction$$anonfun$extract$5.apply(Extraction.scala:382)
at org.json4s.Extraction$.customOrElse(Extraction.scala:606)
at org.json4s.Extraction$.extract(Extraction.scala:382)
at org.json4s.Extraction$.extract(Extraction.scala:39)
at org.json4s.ExtractableJsonAstNode.extract(ExtractableJsonAstNode.scala:21)
at org.json4s.jackson.Serialization$.read(Serialization.scala:50)
at org.json4s.Serialization$class.read(Serialization.scala:30)
at org.json4s.jackson.Serialization$.read(Serialization.scala:17)
其中Contact
是
abstract class Contact[Field : Validable](
val field: Field,
val created: Long,
val updated: Long,
val note: String) { }
和Mail
是
case class Mail(
override val field: String,
override val created: Long = System.currentTimeMillis(),
override val updated: Long = System.currentTimeMillis(),
override val note: String)
extends Contact[String](field, created, updated, note)(Mail)
case object Mail extends Validable[String] {
override def valid(field: String): Boolean = {
Validator.email(field)
}
}
和测试输出是
[{"jsonClass":"whatever.core.entities.utility.contact.Mail","field":"[email protected]","created":1508428385266,"updated":1508428385266,"note":"Random note."}]
挖掘到JSON4S的基本代码示出了类型暗示不使用在所有。
我怎么可能会迫使JSON4S使用类型提示?
干杯
答
使用trait
小号实施Contact
,它会工作。
答
这是你如何使用FullTypeHints
一个例子。
您不能隐式询问Validable[Field]
,既不添加多个显式参数列表(这也发生在隐式参数中,请参阅下面的注释),因为它们不受JSON4S支持。
注意:要求Validable[Field]
隐含地与Contact[Field: Validable]
语法等同于添加附加参数列表implicit validable: Validable[Field]
。
你可以,相反,一个附加参数validable: Validable[Field]
添加到Contact
构造或(如在下面的实施例)的validable
字段应该通过扩展Contact
抽象类的具体类(如Mail
)被重写。
trait Validable[T]{
def valid(field: T): Boolean
}
abstract class Contact[Field](
val field: Field, val created: Long,
val updated: Long, val note: String) {
val validable: Validable[Field]
}
object Contacts{ val classList = List(classOf[Mail]) }
case class Mail(
override val field: String,
override val created: Long = System.currentTimeMillis(),
override val updated: Long = System.currentTimeMillis(),
override val note: String
) extends Contact[String](field, created, updated, note){
override val validable: Validable[String] = Mail
}
case object Mail extends Validable[String] {
override def valid(field: String): Boolean = true
}
implicit val formats = DefaultFormats + FullTypeHints(Contacts.classList)
val mail: List[Mail] = List(Mail(field = "[email protected]", note = "Random note."))
val serialized = Serialization.write(mail)
val mailS = Serialization.read[List[Contact[_]]](serialized)
print(mail == mailS)
的serialized
JSON表示如下:
[
{
"jsonClass":"whatever.core.entities.utility.contact$Mail",
"field":"[email protected]",
"created":1509098018776,
"updated":1509098018776,
"note":"Random note."
}
]
你不必(即使它的实际工作),看看我的回答也知道原因。 –