diff --git a/akka-docs/src/main/paradox/serialization-jackson.md b/akka-docs/src/main/paradox/serialization-jackson.md index 72e5cdfb40..7db9903329 100644 --- a/akka-docs/src/main/paradox/serialization-jackson.md +++ b/akka-docs/src/main/paradox/serialization-jackson.md @@ -173,7 +173,17 @@ This can be solved by implementing a custom serialization for the enums. Annotat Scala : @@snip [CustomAdtSerializer.scala](/akka-serialization-jackson/src/test/scala/doc/akka/serialization/jackson/CustomAdtSerializer.scala) { #adt-trait-object } +### Enumerations +Jackson support for Scala Enumerations defaults to serializing a `Value` as a `JsonObject` that includes a +field with the `"value"` and a field with the `"type"` whose value is the FQCN of the enumeration. Jackson +includes the [`@JsonScalaEnumeration`](https://github.com/FasterXML/jackson-module-scala/wiki/Enumerations) to +statically specify the type information to a field. When using the `@JsonScalaEnumeration` annotation the enumeration +value is serialized as a JsonString. + +Scala +: @@snip [JacksonSerializerSpec.scala](/akka-serialization-jackson/src/test/scala/akka/serialization/jackson/JacksonSerializerSpec.scala) { #jackson-scala-enumeration } + @@@ diff --git a/akka-serialization-jackson/src/test/scala/akka/serialization/jackson/JacksonSerializerSpec.scala b/akka-serialization-jackson/src/test/scala/akka/serialization/jackson/JacksonSerializerSpec.scala index f4dffbc3f9..c1010dbf0d 100644 --- a/akka-serialization-jackson/src/test/scala/akka/serialization/jackson/JacksonSerializerSpec.scala +++ b/akka-serialization-jackson/src/test/scala/akka/serialization/jackson/JacksonSerializerSpec.scala @@ -17,7 +17,6 @@ import java.util.logging.FileHandler import scala.collection.immutable import scala.concurrent.duration.FiniteDuration import scala.concurrent.duration._ - import akka.actor.ActorRef import akka.actor.ActorSystem import akka.actor.Address @@ -51,7 +50,9 @@ import com.fasterxml.jackson.core.JsonParser import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.StreamReadFeature import com.fasterxml.jackson.core.StreamWriteFeature +import com.fasterxml.jackson.core.`type`.TypeReference import com.fasterxml.jackson.databind.json.JsonMapper +import com.fasterxml.jackson.module.scala.JsonScalaEnumeration import com.github.ghik.silencer.silent object ScalaTestMessages { @@ -96,6 +97,21 @@ object ScalaTestMessages { final case class OldCommandNotInBindings(name: String) + // #jackson-scala-enumeration + object Planet extends Enumeration { + type Planet = Value + val Mercury, Venus, Earth, Mars, Krypton = Value + } + + // Uses default Jackson serialization format for Scala Enumerations + final case class Alien(name: String, planet: Planet.Planet) extends TestMessage + + // Serializes planet values as a JsonString + class PlanetType extends TypeReference[Planet.type] {} + final case class Superhero(name: String, @JsonScalaEnumeration(classOf[PlanetType]) planet: Planet.Planet) + extends TestMessage + // #jackson-scala-enumeration + } class ScalaTestEventMigration extends JacksonMigration { @@ -463,6 +479,15 @@ class JacksonJsonSerializerSpec extends JacksonSerializerSpec("jackson-json") { deserializeFromJsonString(json, serializer.identifier, serializer.manifest(expected)) should ===(expected) } + "deserialize Enumerations as String when configured" in { + val json = """{"name":"Superman", "planet":"Krypton"}""" + + val expected = Superhero("Superman", Planet.Krypton) + val serializer = serializerFor(expected) + + deserializeFromJsonString(json, serializer.identifier, serializer.manifest(expected)) should ===(expected) + } + "compress large payload with gzip" in { val conf = JacksonObjectMapperProvider.configForBinding("jackson-json", system.settings.config) val compressionAlgo = conf.getString("compression.algorithm") @@ -722,6 +747,14 @@ abstract class JacksonSerializerSpec(serializerName: String) checkSerialization(BooleanCommand(false)) } + "serialize message with Enumeration property (using Jackson legacy format)" in { + checkSerialization(Alien("E.T.", Planet.Mars)) + } + + "serialize message with Enumeration property as a String" in { + checkSerialization(Superhero("Kal El", Planet.Krypton)) + } + "serialize message with Optional property" in { checkSerialization(OptionCommand(Some("abc"))) checkSerialization(OptionCommand(None))