IT干货网

JSON4S 类型提示不起作用

sxdcgaq8080 2025年05月04日 编程设计 113 0

以下测试片段

implicit val formats = DefaultFormats + FullTypeHints(Contacts.classList) 
 
val serialized = Serialization.write(List(Mail(field = "random@mail.com", 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":"random@mail.com","created":1508428385266,"updated":1508428385266,"note":"Random note."}] 

深入研究 JSON4S 的代码库表明根本没有使用类型提示。

如何强制 JSON4S 使用类型提示?

干杯

请您参考如下方法:

实现 Contact使用 trait s,它会起作用。


评论关闭
IT干货网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!