我以前使用过Circe进行案例类序列化/反序列化,并且喜欢如何在没有其他Scala JSON库所需的样板代码的情况下使用它,但是现在遇到了一个问题,我不是确定如何解决。我有一个ADT(带有几个case类实例的密封特征),我想(从我的Akka Http服务使用akka-http-json)对其进行一般性处理(即返回一个List[Foo]
,其中{{1 }}是特征类型),但是当我使用Circe的自动推导(通过Shapeless)这样做时,它将使用特定的案例类名称作为“ discriminator”(例如,如果我的Foo
包含List[Foo]
实例,则结果序列化列表中的每个元素都将具有键Foo1
)。我想消除类型名称作为区分符(即,为了使序列中的每个元素都没有前缀类型名称,例如Foo1
,我只想序列化要包含的case类实例案例类的字段:例如,"Foo1": {"id : "1", name : "First",...}
...基本上,我想消除类型名称键(我不希望前端必须知道每个元素属于哪个具体案例类)
要序列化的列表中的所有元素都将是相同的具体类型,所有这些都将是我的ADT(特征)类型的子类型。可以使用Circe的半自动推导完成,尽管我没有机会确切地知道如何操作。基本上,我想尽可能多地使用Circe的自动推导,但是要避免出现外层类名在产生的JSON中。任何帮助/建议将不胜感激!谢谢!
答案 0 :(得分:1)
您可以按照文档中的说明进行操作:https://circe.github.io/circe/codecs/adt.html
import cats.syntax.functor._
import io.circe.{ Decoder, Encoder }, io.circe.generic.auto._
import io.circe.syntax._
object GenericDerivation {
implicit val encodeEvent: Encoder[Event] = Encoder.instance {
case foo @ Foo(_) => foo.asJson
case bar @ Bar(_) => bar.asJson
case baz @ Baz(_) => baz.asJson
case qux @ Qux(_) => qux.asJson
}
implicit val decodeEvent: Decoder[Event] =
List[Decoder[Event]](
Decoder[Foo].widen,
Decoder[Bar].widen,
Decoder[Baz].widen,
Decoder[Qux].widen
).reduceLeft(_ or _)
}
import GenericDerivation._
import io.circe.parser.decode
decode[Event]("""{ "i": 1000 }""")
// res0: Either[io.circe.Error,Event] = Right(Foo(1000))
(Foo(100): Event).asJson.noSpaces
// res1: String = {"i":100}
答案 1 :(得分:0)
这可能不是最佳答案,但是经过更多搜索之后,这才是我能够找到的。可以不用将类名作为生成的Json的键,而可以将其序列化为以下字段:
implicit val genDevConfig: Configuration.default.withDescriminator("type")
(您可以在此处使用任何字段名称;对于类似的问题,Travis Brown的上一个example使用了名为what_am_i
的字段)。因此,我深表歉意–我尚不知道是否存在针对该问题的规范或广泛接受的解决方案,尤其是使用akka-http-json之类的库可以轻松地与Akka Http一起使用的解决方案,我似乎仍然在遇到一些问题,尽管我确定我可能会忽略一些明显的问题!无论如何,我很抱歉提出一个似乎反复出现的问题!