Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
787 views
in Technique[技术] by (71.8m points)

scala - Noise free JSON format for sealed traits with Play 2.2 library

I need to get a simple JSON serialization solution with minimum ceremony. So I was quite happy finding this forthcoming Play 2.2 library. This works perfectly with plain case classes, e.g.

import play.api.libs.json._

sealed trait Foo
case class Bar(i: Int) extends Foo
case class Baz(f: Float) extends Foo

implicit val barFmt = Json.format[Bar]
implicit val bazFmt = Json.format[Baz]

But the following fails:

implicit val fooFmt = Json.format[Foo]   // "No unapply function found"

How would I set up the alleged missing extractor for Foo?

Or would you recommend any other standalone library that handles my case more or less fully automatically? I don't care whether that is with macros at compile time or reflection at runtime, as long as it works out of the box.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

AMENDED 2015-09-22

The library play-json-extra includes the play-json-variants strategy, but also the [play-json-extensions] strategy (flat string for case objects mixed with objects for case classes no extra $variant or $type unless needed). It also provides serializers and deserializers for macramé based enums.

Previous answer There is now a library called play-json-variants which allows you to write :

implicit val format: Format[Foo] = Variants.format[Foo]

This will generate the corresponding formats automatically, it will also handle disambiguation of the following case by adding a $variant attribute (the equivalent of 0__ 's class attribute)

sealed trait Foo
case class Bar(x: Int) extends Foo
case class Baz(s: String) extends Foo
case class Bah(s: String) extends Foo

would generate

val bahJson = Json.obj("s" -> "hello", "$variant" -> "Bah") // This is a `Bah`
val bazJson = Json.obj("s" -> "bye", "$variant" -> "Baz") // This is a `Baz`
val barJson = Json.obj("x" -> "42", "$variant" -> "Bar") // And this is a `Bar`

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...