我有大量的案例类,其中以下只是这些案例类的子集:
I have a huge set of case classes where below is just a subset of these case classes:
sealed trait BuiltInType { def id: Int } case class ZombieType (a: String, id: Int = 0) extends BuiltInType case class BooleanType (a: Boolean, id: Int = 1) extends BuiltInType case class ByteType (a: Byte, id: Int = 2) extends BuiltInType case class UByteType (a: Byte, id: Int = 3) extends BuiltInType case class Int16Type (a: Int, id: Int = 4) extends BuiltInType case class UInt16Type (a: Int, id: Int = 5) extends BuiltInType case class Int32Type (a: Int, id: Int = 6) extends BuiltInType case class UInt32Type (a: Int, id: Int = 7) extends BuiltInType case class Int64Type (a: Long, id: Int = 8) extends BuiltInType case class UInt64Type (a: Long, id: Int = 9) extends BuiltInType case class FloatType (a: Float, id: Int = 10) extends BuiltInType case class DoubleType (a: Double, id: Int = 11) extends BuiltInType case class StringType (a: String, id: Int = 12) extends BuiltInType case class DateTimeType (a: Long, id: Int = 13) extends BuiltInType // FIXME: Wrong type used, fix it later case class GuidType (a: UUID, id: Int = 14) extends BuiltInType case class ByteStringType (a: Vector[Byte], id: Int = 15) extends BuiltInType case class XmlElementType (a: String, id: Int = 16) extends BuiltInType case class NodeIdType (a: NodeId, id: Int = 17) extends BuiltInType case class ExpandedNodeIdType (a: NodeId, id: Int = 18) extends BuiltInType // FIXME: Wrong type used, fix it later case class StatusCodeType (a: StatusCode, id: Int = 19) extends BuiltInType case class QualifiedNameType (a: QualifiedName, id: Int = 20) extends BuiltInType case class LocalizedTextType (a: LocalizedText, id: Int = 21) extends BuiltInType case class ExtensionObjectType (a: ExtensionObject, id: Int = 22) extends BuiltInType case class DataValueType (a: DataValue, id: Int = 23) extends BuiltInType case class VariantType (a: Variant, id: Int = 24) extends BuiltInType case class DiagnosticInfoType (a: String, id: Int = 25) extends BuiltInType如您所见,我还定义了其他几种复杂类型.例如,有一个名为Variant的类型,它本身是一个case类,如下所示:
As you can see that I have several other complex types defined. For example., there is a type called Variant which itself is a case class like this:
sealed trait VariantData case class SimpleOrder(rows: Vector[BuiltInType]) extends VariantData case class HigherOrder(matrices: Vector[VariantData]) extends VariantData case class Variant(data: VariantData)然后我为Play JSON定义所有必需的隐式格式,如下所示:
I then define all the needed implicit formats for Play JSON like this:
implicit val strType = Json.format[StringType] implicit val guidType = Json.format[GuidType] implicit val int16Type = Json.format[Int16Type] implicit val uint64Type = Json.format[UInt64Type] implicit val int32Type = Json.format[Int32Type] implicit val int64Type = Json.format[Int64Type] implicit val uByteTyp = Json.format[UByteType] implicit val qNameType = Json.format[QualifiedNameType] implicit val nodeIdTyp = Json.format[NodeIdType] implicit val locTextTyp = Json.format[LocalizedTextType] implicit val zombType = Json.format[ZombieType] implicit val statusCodeTyp = Json.format[StatusCodeType] implicit val builtInType = Json.format[BuiltInType] implicit val simpleFmt = Json.format[SimpleOrder] implicit val higherFmt = Json.format[HigherOrder] implicit val varDataFmt = Json.format[VariantData] implicit val varFmt = Json.format[Variant]我收到此错误:
Error:(66, 43) No instance of Reads is available for domain.CommonTypes.VariantType in the implicit scope (Hint: if declared in the same file, make sure it's declared before) implicit val builtInType = Json.format[BuiltInType]所以我这样改变了隐式的顺序:
So I changed the order of implicits like this:
implicit val simpleFmt = Json.format[SimpleOrder] implicit val higherFmt = Json.format[HigherOrder] implicit val varDataFmt = Json.format[VariantData] implicit val varFmt = Json.format[Variant] implicit val strType = Json.format[StringType] implicit val guidType = Json.format[GuidType] implicit val int16Type = Json.format[Int16Type] implicit val uint64Type = Json.format[UInt64Type] implicit val int32Type = Json.format[Int32Type] implicit val int64Type = Json.format[Int64Type] implicit val uByteTyp = Json.format[UByteType] implicit val qNameType = Json.format[QualifiedNameType] implicit val nodeIdTyp = Json.format[NodeIdType] implicit val locTextTyp = Json.format[LocalizedTextType] implicit val zombType = Json.format[ZombieType] implicit val statusCodeTyp = Json.format[StatusCodeType] implicit val builtInType = Json.format[BuiltInType]但是现在,我收到此错误:
But now, I get this error:
Error:(53, 41) No instance of play.api.libs.json.Format is available for scala.collection.immutable.Vector[domain.CommonTypes.BuiltInType] in the implicit scope (Hint: if declared in the same file, make sure it's declared before) implicit val simpleFmt = Json.format[SimpleOrder]现在我的问题是,这是订购问题还是我缺少的东西,因为这里的抱怨是期望
So my question now is, is this an ordering problem or is there something that I'm missing as the complain here is that it is expecting a
Vector [BuiltInType]
Vector[BuiltInType]
还是循环依赖性导致了此问题?
Or is the cyclic dependency causing this problem?
推荐答案通常,您总是可以解决订购问题,例如:
In general you can always fix problems with ordering like:
将formats放在companion-objects中.
请参见下面的示例.
要简化使用sealed traits的工作,我会使用 play-json衍生的编解码器
To simplify your work with sealed traits I would use play-json-derived-codecs
进口:
import play.api.libs.json._ import julienrf.json.derived很酷的事情是,您只需要format trait,它的所有subclasses都将自动完成:
The cool thing is you only need to format the trait, all its subclasses will be done automatically:
implicit val jsonFormat: OFormat[VariantData] = derived.oformat[VariantData]() implicit val jsonFormat: OFormat[BuiltInType] = derived.oformat[BuiltInType]()format代码略有不同.
为演示如何简化此处的代码,请参见 Dmytro 的示例:
To illustrate how this simplifies the code here is Dmytro's example:
import play.api.libs.json._ import julienrf.json.derived sealed trait BuiltInType { def id: Int } case class StringType(a: String, id: Int = 12) extends BuiltInType case class ByteStringType(a: Seq[Byte], id: Int = 15) extends BuiltInType case class VariantType(a: Variant, id: Int = 24) extends BuiltInType object BuiltInType { implicit val jsonFormat: OFormat[BuiltInType] = derived.oformat[BuiltInType]() } sealed trait VariantData case class SimpleOrder(rows: Seq[BuiltInType]) extends VariantData case class HigherOrder(matrices: Seq[VariantData]) extends VariantData object VariantData { implicit val jsonFormat: OFormat[VariantData] = derived.oformat[VariantData]() } case class Variant(data: VariantData) object Variant { implicit val jsonFormat: OFormat[Variant] = derived.oformat[Variant]() } val json = Json.toJson(VariantType(Variant(SimpleOrder(Seq(StringType("aaa"))))): BuiltInType) println(json) //{"a":{"data":{"_type":"App.SimpleOrder","rows":[{"a":"aaa","_type":"App.StringType","id":12}]}},"_type":"App.VariantType","id":24}以您的示例为例,差异会更大.
With your example the difference will be even bigger.
更多推荐
Play Framework JSON无法排序
发布评论