Merge pull request #5 from banjjoknim/jackson
ContextualSerializer 를 사용하는 직렬화 예제 코드 추가
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package com.banjjoknim.playground.jackson.common
|
||||
|
||||
import com.banjjoknim.playground.jackson.jsonserialize.ContextualCarSerializer
|
||||
import com.banjjoknim.playground.jackson.jsonserialize.UsingJsonSerializeAnnotationCarSerializer
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize
|
||||
|
||||
@@ -16,7 +17,7 @@ data class CarUsingNoAnnotation(
|
||||
val owner: Owner = Owner()
|
||||
)
|
||||
|
||||
data class CarUsingJsonSerializeAnnotation(
|
||||
data class CarUsingJsonSerializeAnnotationCarSerializer(
|
||||
val name: String = "banjjoknim",
|
||||
@JsonSerialize(using = UsingJsonSerializeAnnotationCarSerializer::class)
|
||||
val secret: String = "secret",
|
||||
@@ -24,6 +25,23 @@ data class CarUsingJsonSerializeAnnotation(
|
||||
val owner: Owner = Owner()
|
||||
)
|
||||
|
||||
data class CarUsingContextualSerializerWithSecretAnnotation(
|
||||
val name: String = "banjjoknim",
|
||||
@JsonSerialize(using = ContextualCarSerializer::class)
|
||||
@field:Secret("hello world!!")
|
||||
val secret: String = "secret",
|
||||
val price: Int = 10000000,
|
||||
val owner: Owner = Owner()
|
||||
)
|
||||
|
||||
data class CarUsingContextualSerializerWithNoSecretAnnotation(
|
||||
val name: String = "banjjoknim",
|
||||
@JsonSerialize(using = ContextualCarSerializer::class)
|
||||
val secret: String = "secret",
|
||||
val price: Int = 10000000,
|
||||
val owner: Owner = Owner()
|
||||
)
|
||||
|
||||
data class CarUsingSecretAnnotation(
|
||||
val name: String = "banjjoknim",
|
||||
@field:Secret("****")
|
||||
|
||||
@@ -4,6 +4,8 @@ import com.banjjoknim.playground.jackson.common.Car
|
||||
import com.banjjoknim.playground.jackson.common.Secret
|
||||
import com.fasterxml.jackson.core.JsonGenerator
|
||||
import com.fasterxml.jackson.databind.BeanDescription
|
||||
import com.fasterxml.jackson.databind.BeanProperty
|
||||
import com.fasterxml.jackson.databind.JsonSerializer
|
||||
import com.fasterxml.jackson.databind.SerializationConfig
|
||||
import com.fasterxml.jackson.databind.SerializerProvider
|
||||
import com.fasterxml.jackson.databind.introspect.Annotated
|
||||
@@ -12,6 +14,7 @@ import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule
|
||||
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter
|
||||
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier
|
||||
import com.fasterxml.jackson.databind.ser.ContextualSerializer
|
||||
import com.fasterxml.jackson.databind.ser.std.StdSerializer
|
||||
|
||||
/**
|
||||
@@ -83,6 +86,24 @@ class UsingJsonSerializeAnnotationCarSerializer : StdSerializer<String>(String::
|
||||
}
|
||||
}
|
||||
|
||||
class ContextualCarSerializer(
|
||||
private val substituteValue: String = "this is default value in ContextualCarSerializer"
|
||||
) : StdSerializer<String>(String::class.java), ContextualSerializer {
|
||||
override fun serialize(value: String, gen: JsonGenerator, provider: SerializerProvider) {
|
||||
gen.writeString(substituteValue)
|
||||
}
|
||||
|
||||
override fun createContextual(provider: SerializerProvider, property: BeanProperty): JsonSerializer<*> {
|
||||
val annotation = property.getAnnotation(Secret::class.java)
|
||||
if (annotation != null) {
|
||||
return ContextualCarSerializer(annotation.substituteValue)
|
||||
}
|
||||
return ContextualCarSerializer()
|
||||
// JsonMappingException: Can not write a field name, expecting a value (through reference chain: com.banjjoknim.playground.jackson.common.CarUsingContextualSerializerWithNoSecretAnnotation["secret"])
|
||||
// return provider.findKeySerializer(property.type, property)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AnnotationIntrospector 를 상속한 JacksonAnnotationIntrospector 은 Jackson 라이브러리가 직렬화/역직렬화시 `JacksonAnnotation` 정보를 어떻게 처리할지에 대한 정보가 정의되어 있는 클래스다.
|
||||
*
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.banjjoknim.playground.jackson.jsonserialize
|
||||
|
||||
import com.banjjoknim.playground.jackson.common.Car
|
||||
import com.banjjoknim.playground.jackson.common.CarUsingJsonSerializeAnnotation
|
||||
import com.banjjoknim.playground.jackson.common.CarUsingContextualSerializerWithNoSecretAnnotation
|
||||
import com.banjjoknim.playground.jackson.common.CarUsingContextualSerializerWithSecretAnnotation
|
||||
import com.banjjoknim.playground.jackson.common.CarUsingJsonSerializeAnnotationCarSerializer
|
||||
import com.banjjoknim.playground.jackson.common.CarUsingNoAnnotation
|
||||
import com.banjjoknim.playground.jackson.common.CarUsingSecretAnnotation
|
||||
import com.banjjoknim.playground.jackson.common.Owner
|
||||
@@ -32,7 +34,11 @@ class CarSerializersTest {
|
||||
private val owner = Owner("ban", 30)
|
||||
private val car = Car("banjjoknim", 10_000_000, owner)
|
||||
private val carUsingNoAnnotation = CarUsingNoAnnotation()
|
||||
private val carUsingJsonSerializeAnnotation = CarUsingJsonSerializeAnnotation()
|
||||
private val carUsingJsonSerializeAnnotationCarSerializer = CarUsingJsonSerializeAnnotationCarSerializer()
|
||||
private val carUsingContextualSerializerWithSecretAnnotation =
|
||||
CarUsingContextualSerializerWithSecretAnnotation()
|
||||
private val carUsingContextualSerializerWithNoSecretAnnotation =
|
||||
CarUsingContextualSerializerWithNoSecretAnnotation()
|
||||
private val carUsingSecretAnnotation = CarUsingSecretAnnotation()
|
||||
}
|
||||
|
||||
@@ -141,12 +147,26 @@ class CarSerializersTest {
|
||||
// given
|
||||
|
||||
// when
|
||||
val actual = mapper.writeValueAsString(carUsingJsonSerializeAnnotation)
|
||||
val actual = mapper.writeValueAsString(carUsingJsonSerializeAnnotationCarSerializer)
|
||||
|
||||
// then
|
||||
assertThat(actual).isEqualTo("""{"name":"banjjoknim","secret":"****","price":10000000,"owner":{"name":"ban","age":30}}""")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ContextualSerializer 를 상속 받은 구현체를 이용해서 직렬화한다`() {
|
||||
// given
|
||||
|
||||
// when
|
||||
val actualWithSecretAnnotation = mapper.writeValueAsString(carUsingContextualSerializerWithSecretAnnotation)
|
||||
val actualWithNoSecretAnnotation =
|
||||
mapper.writeValueAsString(carUsingContextualSerializerWithNoSecretAnnotation)
|
||||
|
||||
// then
|
||||
assertThat(actualWithSecretAnnotation).isEqualTo("""{"name":"banjjoknim","secret":"hello world!!","price":10000000,"owner":{"name":"ban","age":30}}""")
|
||||
assertThat(actualWithNoSecretAnnotation).isEqualTo("""{"name":"banjjoknim","secret":"this is default value in ContextualCarSerializer","price":10000000,"owner":{"name":"ban","age":30}}""")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `@Secret 어노테이션, AnnotationIntrospector 을 적용하여 직렬화한다`() {
|
||||
// given
|
||||
@@ -239,7 +259,10 @@ class CarSerializersTest {
|
||||
|
||||
// when
|
||||
mapper.setAnnotationIntrospector(
|
||||
AnnotationIntrospector.pair(SecretAnnotationIntrospector(), originalAnnotationIntrospector) // 내부 구현은 아래와 같다.
|
||||
AnnotationIntrospector.pair(
|
||||
SecretAnnotationIntrospector(),
|
||||
originalAnnotationIntrospector
|
||||
) // 내부 구현은 아래와 같다.
|
||||
// AnnotationIntrospectorPair(SecretAnnotationIntrospector(), originalAnnotationIntrospector)
|
||||
)
|
||||
val allIntrospectorNames = mapper.serializationConfig.annotationIntrospector.allIntrospectors()
|
||||
|
||||
Reference in New Issue
Block a user