2017-10-19 27 views
6

Sau đây đoạn thử nghiệmJSON4S loại gợi ý không làm việc

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) 

không thành công với

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) 

nơi 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) 
    } 
} 

và đầu ra thử nghiệm là

[{"jsonClass":"whatever.core.entities.utility.contact.Mail","field":"[email protected]","created":1508428385266,"updated":1508428385266,"note":"Random note."}] 

Đào vào codebase của JSON4S cho thấy rằng loại gợi ý không được sử dụng ở tất cả.

Làm cách nào để buộc JSON4S sử dụng gợi ý loại?

Chúc mừng

Trả lời

0

Thực hiện Contact sử dụng trait s và nó sẽ làm việc.

+0

Bạn không cần phải (ngay cả khi nó thực sự hoạt động), có một cái nhìn vào câu trả lời của tôi cũng biết nguyên nhân. –

0

Đây là ví dụ về cách bạn có thể sử dụng FullTypeHints.

Bạn không thể yêu cầu ngầm cho Validable[Field], không thêm nhiều danh sách đối số rõ ràng (và điều này cũng xảy ra với các tham số ngầm định), vì chúng không được hỗ trợ bởi JSON4S.

Lưu ý: yêu cầu Validable[Field] hoàn toàn với cú pháp Contact[Field: Validable] bằng với việc thêm danh sách đối số bổ sung với implicit validable: Validable[Field].

Bạn có thể, thay vào đó, thêm một tham số bổ sung validable: Validable[Field] để các nhà xây dựng Contact hoặc (như trong ví dụ dưới đây) một lĩnh vực validable đó nên được ghi đè bởi lớp bê tông (như Mail) mở rộng lớp trừu tượng Contact.

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) 

Các serialized JSON đại diện được những điều sau đây:

[ 
    { 
    "jsonClass":"whatever.core.entities.utility.contact$Mail", 
    "field":"[email protected]", 
    "created":1509098018776, 
    "updated":1509098018776, 
    "note":"Random note." 
    } 
] 
+0

Đây không phải là mã giống như tôi? – Dyin

+0

Xin lỗi, tôi đã bỏ lỡ sự cần thiết của 'Trường hợp pháp lý ', đã cập nhật câu trả lời của tôi để đối phó với điều đó. Bây giờ nó hoàn toàn nên trả lời câu hỏi của bạn. –

+0

Cảm ơn, nhưng điều đó sẽ không hoạt động, vì 'Contact [Field]' là một lớp trừu tượng. 'Contact [Field]' phải là một đặc điểm. – Dyin

Các vấn đề liên quan