Skip to content

two enums #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ repositories {
mavenCentral()
}

compileScala.targetCompatibility = 1.8
ScalaCompileOptions.metaClass.useAnt = false

dependencies {
compile group: 'org.scala-lang', name: 'scala-library', version: '2.12.8'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.1.3.RELEASE'
Expand Down
64 changes: 54 additions & 10 deletions src/main/scala/org/example/configuration/JacksonConfiguration.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ import com.fasterxml.jackson.databind.deser.std.StdDeserializer
import com.fasterxml.jackson.databind.{DeserializationContext, JsonNode, ObjectMapper, SerializerProvider}
import com.fasterxml.jackson.databind.module.SimpleModule
import com.fasterxml.jackson.databind.ser.std.StdSerializer
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import org.example.configuration.JacksonConfiguration.{GenderJsonDeserializer, GenderJsonSerializer}
import org.example.model.Person.Gender
import com.fasterxml.jackson.module.scala.deser.{ScalaNumberDeserializersModule, UntypedObjectDeserializerModule}
import com.fasterxml.jackson.module.scala.introspect.ScalaAnnotationIntrospectorModule
import com.fasterxml.jackson.module.scala.{DefaultScalaModule, EitherModule, EnumerationModule, IterableModule, IteratorModule, JacksonModule, MapModule, OptionModule, SeqModule, SetModule, TupleModule}
import org.example.configuration.JacksonConfiguration.{FaceJsonDeserializer, FaceJsonSerializer, GenderJsonDeserializer, GenderJsonSerializer}
import org.example.model.Person.Face.Face
import org.example.model.Person.{Face, FaceEnum, Gender, GenderEnum}
import org.example.model.Person.Gender.Gender
import org.springframework.context.annotation.{Bean, Configuration}

Expand All @@ -17,11 +20,17 @@ class JacksonConfiguration {
@Bean
def objectMapper: ObjectMapper = {
val objectMapper = new ObjectMapper()
objectMapper.registerModule(DefaultScalaModule)
val genderSerializerModule = new SimpleModule()
genderSerializerModule.addSerializer(new GenderJsonSerializer())
genderSerializerModule.addDeserializer(classOf[Gender.Gender], new GenderJsonDeserializer())
objectMapper.registerModule(genderSerializerModule)
objectMapper.registerModule(MyScalaModule)
val genderSerializerModule = new SimpleModule()
genderSerializerModule.addSerializer(new GenderJsonSerializer())
genderSerializerModule.addDeserializer(classOf[Gender.Gender], new GenderJsonDeserializer())
objectMapper.registerModule(genderSerializerModule)

val faceSerializerModule = new SimpleModule()
faceSerializerModule.addSerializer(new FaceJsonSerializer())
faceSerializerModule.addDeserializer(classOf[Face], new FaceJsonDeserializer())
objectMapper.registerModule(faceSerializerModule)

objectMapper
}
}
Expand All @@ -30,18 +39,53 @@ object JacksonConfiguration {

class GenderJsonSerializer extends StdSerializer[Gender.Gender](classOf[Gender.Gender]) {

def this(t: Gender.type) = this()
def this(t: GenderEnum) = this()

override def serialize(value: Gender, gen: JsonGenerator, provider: SerializerProvider): Unit =
gen.writeString(value.toString)
}

class GenderJsonDeserializer extends StdDeserializer[Gender.Gender](classOf[Gender.Gender]) {

def this(t: Gender.type ) = this()
def this(t: GenderEnum) = this()

override def deserialize(p: JsonParser, ctxt: DeserializationContext): Gender =
Gender.withName(p.getCodec.readTree(p).asInstanceOf[JsonNode].asText())
}


class FaceJsonSerializer extends StdSerializer[Face](classOf[Face]) {

def this(t: FaceEnum) = this()

override def serialize(value: Face, gen: JsonGenerator, provider: SerializerProvider): Unit =
gen.writeString(value.toString)
}

class FaceJsonDeserializer extends StdDeserializer[Face](classOf[Face]) {

def this(t: FaceEnum) = this()

override def deserialize(p: JsonParser, ctxt: DeserializationContext): Face =
Face.withName(p.getCodec.readTree(p).asInstanceOf[JsonNode].asText())
}

}

class MyScalaModule
extends JacksonModule
with IteratorModule
with OptionModule
with SeqModule
with IterableModule
with TupleModule
with MapModule
with SetModule
with ScalaNumberDeserializersModule
with ScalaAnnotationIntrospectorModule
with UntypedObjectDeserializerModule
with EitherModule {
override def getModuleName = "MyScalaModule"
}

object MyScalaModule extends MyScalaModule
34 changes: 29 additions & 5 deletions src/main/scala/org/example/model/Person.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package org.example.model

import org.example.model.Person.Gender
import java.util

import com.fasterxml.jackson.databind.annotation.JsonDeserialize
import org.example.model.Person.{Face, Gender}

import scala.beans.BeanProperty
import scala.util.Random
Expand All @@ -9,26 +12,47 @@ case class Person(
@BeanProperty var name: String,
@BeanProperty var age: Int,
@BeanProperty var hobbies: List[String],

@BeanProperty
@JsonDeserialize(using = classOf[org.example.configuration.JacksonConfiguration.GenderJsonDeserializer])
var gender: Gender.Gender,

@BeanProperty
var gender: Gender.Gender
@JsonDeserialize(using = classOf[org.example.configuration.JacksonConfiguration.FaceJsonDeserializer])
var face: Face.Face,

) {
def this() = this("", 0, List(), Gender.MALE)
def this() = this("", 0, List(), Gender.MALE, Face.BIG_FACE)
}

object Person {

object Gender extends Enumeration {
trait GenderEnum {
this: scala.Enumeration =>
}

object Gender extends Enumeration with GenderEnum {
type Gender = Value
val MALE, FEMALE = Value
}

trait FaceEnum {
this: scala.Enumeration =>
}

object Face extends Enumeration with FaceEnum {
type Face = Value
val BIG_FACE, SMALL_FACE = Value
}

private val names = List("Zorro", "Morro", "Korro")
private val hobbies = List("killing", "stealing", "hiking", "swimming", "sleeping")

def randomPerson: Person = Person(
Random.shuffle(names).head,
Random.nextInt(100),
Random.shuffle(hobbies).take(2),
Random.shuffle(Gender.values.toList).head
Random.shuffle(Gender.values.toList).head,
Random.shuffle(Face.values.toList).head
)
}
14 changes: 7 additions & 7 deletions src/test/scala/org/example/JsonSerializationTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package org.example

import org.example.configuration.JacksonConfiguration
import org.example.model.Person
import org.example.model.Person.Gender
import org.example.model.Person.{Face, Gender}
import org.junit.runner.RunWith
import org.scalatest.{FlatSpec, Matchers}
import org.scalatestplus.junit.JUnitRunner
Expand All @@ -11,31 +11,31 @@ import org.scalatestplus.junit.JUnitRunner
class JsonSerializationTest extends FlatSpec with Matchers {

"Jackson serializer" should "serialize a Person into JSON" in {
val samplePerson = Person("Zorro", 15, List("Lego", "Piano"), Gender.MALE)
val samplePerson = Person("Zorro", 15, List("Lego", "Piano"), Gender.MALE, Face.SMALL_FACE)
val mapper = new JacksonConfiguration().objectMapper
val actualJson = mapper.writerFor(classOf[Person]).writeValueAsString(samplePerson)
val expectedJson = """{"name":"Zorro","age":15,"hobbies":["Lego","Piano"],"gender":"MALE"}"""
val expectedJson = """{"name":"Zorro","age":15,"hobbies":["Lego","Piano"],"gender":"MALE","face":"SMALL_FACE"}"""

actualJson should equal(expectedJson)
}

it should "deserialize a Person from JSON string" in {
val sampleJson = """{"name":"Zorro","age":15,"hobbies":["Lego","Piano"],"gender":"MALE"}"""
val sampleJson = """{"name":"Zorro","age":15,"hobbies":["Lego","Piano"],"gender":"MALE","face":"BIG_FACE"}"""
val mapper = new JacksonConfiguration().objectMapper
val actualPerson = mapper.readValue(sampleJson, classOf[Person])
val expectedPerson = Person("Zorro", 15, List("Lego", "Piano"), Gender.MALE)
val expectedPerson = Person("Zorro", 15, List("Lego", "Piano"), Gender.MALE, Face.BIG_FACE)

actualPerson should equal(expectedPerson)
}

it should "serialize and deserialize random Persons 1000 times" in {
for(i <- 0 to 1000) {
for (i <- 0 to 1000) {
val randomPerson = Person.randomPerson
val mapper = new JacksonConfiguration().objectMapper
val jsonString = mapper.writerFor(classOf[Person]).writeValueAsString(randomPerson)
val actualPerson = mapper.readValue(jsonString, classOf[Person])

actualPerson should equal (randomPerson)
actualPerson should equal(randomPerson)
}
}
}