我有一个抽象的类和对象
sealed abstract class Granularity() {
// some values and methods
}
object Granularity {
final private case class WeekGranularity(name: String, windowSize: Int) extends Granularity("week", "'7' day") {
// overriding methods
}
val Week: Granularity = WeekGranularity(name = "week", windowSize = 1)
}我在其他一些类似的类中使用它
case class Meta(granularity: Granularity)
object Meta {
implicit val granularityWrites = Writes[Granularity](d => JsString(d.toString))
implicit val metaWrites = Json.writes[Meta]
}现在,当编写这样的规范时,我得到了一个错误
class ControllerSpec {
"MetaController" should {
"return" {
.
.
.
// play 2.13 resp
resp.body[JsValue].asOpt[Meta] should beSome(expectedMeta)
// ERROR: No Json deserializer found for type models.Meta. Try to implement an implicit Reads or Format for this type
}
}
}当我在Spec类的顶部添加隐式读取时,我仍然得到一个错误
implicit val granularityReads = Json.reads[Granularity] // ERROR: Sealed trait Granularity is not supported: no known subclasses
implicit val metaReads = Json.reads[Meta]我可以这样做来比较json,它是有效的,我不需要创建任何隐式的。
resp.body[JsValue] shouldEqual Json.toJson(metricSignTimeseries)但我想知道如何在粒度上实现隐式读取?
发布于 2021-08-20 11:18:45
为了从JSON数据中读取Granularity,该库必须能够创建一个Granularity实例来返回它。但是Granularity是一个abstract class,您不能创建抽象类的实例。
Json.reads需要使用可由库实例化的具体类进行参数化,或者您需要编写一个自定义Reads[Granularity]来创建并返回Granularity的适当子类。
我建议您不要将功能放在用于读/写JSON或使用复杂类层次结构的类中。只需将数据读取到直接匹配JSON格式的简单case class实例中,然后将它们处理成应用程序类。这允许存储格式和内部应用程序数据格式独立改变,而不是紧密地联系在一起。
https://stackoverflow.com/questions/68853382
复制相似问题