jackson-kotlin
KotlinのJacksonサポート
1. 概要
このチュートリアルでは、Kotlinのlink:/jackson-annotations[Jackson]サポートについて説明します。
__Object__sと__Collection__sの両方をシリアライズおよびデシリアライズする方法を検討します。 _ @ JsonProperty_および_ @ JsonInclude_アノテーションも使用します。
2. Mavenの構成
まず、_pom.xml_に_jackson-module-kotlin_依存関係を追加する必要があります。
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
<version>2.9.8</version>
</dependency>
_https://search.maven.org/search?q = a:jackson-module-kotlin%20AND%20g:com.fasterxml.jackson.module [jackson-module-kotlin] _の最新バージョンはMavenにありますセントラル。
3. _Object_シリアル化
オブジェクトのシリアル化から始めましょう。
ここに、例で使用する簡単なデータ_Movie_クラスがあります。
data class Movie(
var name: String,
var studio: String,
var rating: Float? = 1f)
オブジェクトをシリアライズおよびデシリアライズするには、* Kotlinの_ObjectMapper_のインスタンスが必要です。
_jacksonObjectMapper()_を使用して作成できます。
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
val mapper = jacksonObjectMapper()
または、_ObjectMapper_を作成してから_KotlinModule_を登録できます。
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.KotlinModule
val mapper = ObjectMapper().registerModule(KotlinModule())
マッパーができたので、それを使用して単純な_Movie_オブジェクトをシリアル化しましょう。
*メソッド_writeValueAsString()_:*を使用して、オブジェクトをJSON文字列にシリアル化できます。
@Test
fun whenSerializeMovie_thenSuccess() {
val movie = Movie("Endgame", "Marvel", 9.2f)
val serialized = mapper.writeValueAsString(movie)
val json = """
{
"name":"Endgame",
"studio":"Marvel",
"rating":9.2
}"""
assertEquals(serialized, json)
}
4. _Object_逆シリアル化
次に、マッパーを使用してJSON文字列を_Movie_インスタンスに逆シリアル化します。
メソッド_readValue()_を使用します。
@Test
fun whenDeserializeMovie_thenSuccess() {
val json = """{"name":"Endgame","studio":"Marvel","rating":9.2}"""
val movie: Movie = mapper.readValue(json)
assertEquals(movie.name, "Endgame")
assertEquals(movie.studio, "Marvel")
assertEquals(movie.rating, 9.2f)
}
-
_TypeReference_を_readValue()_メソッドに提供する必要がないことに注意してください。変数の型を指定するだけです。*
別の方法でクラスタイプを指定することもできます。
val movie = mapper.readValue<Movie>(json)
逆シリアル化中に、フィールドが_JSON_ Stringにない場合、マッパーはそのフィールドのクラスで宣言されたデフォルト値を使用します。
ここでは、JSON文字列に_rating_フィールドがないため、デフォルト値_1_が使用されました。
@Test
fun whenDeserializeMovieWithMissingValue_thenUseDefaultValue() {
val json = """{"name":"Endgame","studio":"Marvel"}"""
val movie: Movie = mapper.readValue(json)
assertEquals(movie.name, "Endgame")
assertEquals(movie.studio, "Marvel")
assertEquals(movie.rating, 1f)
}
5. Mapsでの作業
次に、Jacksonを使用して__Map__sをシリアル化および逆シリアル化する方法について説明します。
ここでは、単純な_Map <Int、String> _をシリアル化します。
@Test
fun whenSerializeMap_thenSuccess() {
val map = mapOf(1 to "one", 2 to "two")
val serialized = mapper.writeValueAsString(map)
val json = """
{
"1":"one",
"2":"two"
}"""
assertEquals(serialized, json)
}
次に、*マップをデシリアライズするとき、キーと値のタイプを指定する必要があります*:
@Test
fun whenDeserializeMap_thenSuccess() {
val json = """{"1":"one","2":"two"}"""
val aMap: Map<Int,String> = mapper.readValue(json)
assertEquals(aMap[1], "one")
assertEquals(aMap[2], "two")
}
6. Collectionsの使用
次に、Kotlinでコレクションをシリアル化する方法について説明します。
ここに、JSON文字列にシリアル化する映画の_List_があります。
@Test
fun whenSerializeList_thenSuccess() {
val movie1 = Movie("Endgame", "Marvel", 9.2f)
val movie2 = Movie("Shazam", "Warner Bros", 7.6f)
val movieList = listOf(movie1, movie2)
val serialized = mapper.writeValueAsString(movieList)
val json = """
[
{
"name":"Endgame",
"studio":"Marvel",
"rating":9.2
},
{
"name":"Shazam",
"studio":"Warner Bros",
"rating":7.6
}
]"""
assertEquals(serialized, json)
}
_List_をデシリアライズするとき、_Map_で行ったように、オブジェクトタイプ_Movie_を提供する必要があります。
@Test
fun whenDeserializeList_thenSuccess() {
val json = """[{"name":"Endgame","studio":"Marvel","rating":9.2},
{"name":"Shazam","studio":"Warner Bros","rating":7.6}]"""
val movieList: List<Movie> = mapper.readValue(json)
val movie1 = Movie("Endgame", "Marvel", 9.2f)
val movie2 = Movie("Shazam", "Warner Bros", 7.6f)
assertTrue(movieList.contains(movie1))
assertTrue(movieList.contains(movie2))
}
7. フィールド名を変更する
次に、* _ JsonProperty_アノテーションを使用して、シリアル化および逆シリアル化中にフィールド名を変更できます*。
この例では、_Book_データクラスの_authorName_フィールドの名前を_author_に変更します。
data class Book(
var title: String,
@JsonProperty("author") var authorName: String)
_Book_オブジェクトをシリアル化すると、_authorName_の代わりに_author_が使用されます。
@Test
fun whenSerializeBook_thenSuccess() {
val book = Book("Oliver Twist", "Charles Dickens")
val serialized = mapper.writeValueAsString(book)
val json = """
{
"title":"Oliver Twist",
"author":"Charles Dickens"
}"""
assertEquals(serialized, json)
}
同じことが逆シリアル化にも当てはまります。
@Test
fun whenDeserializeBook_thenSuccess() {
val json = """{"title":"Oliver Twist", "author":"Charles Dickens"}"""
val book: Book = mapper.readValue(json)
assertEquals(book.title, "Oliver Twist")
assertEquals(book.authorName, "Charles Dickens")
}
8. 空のフィールドを除外する
最後に、空のフィールドをシリアル化から除外する方法について説明します。
_Book_クラスに_genres_という新しいフィールドを追加しましょう。 このフィールドは、デフォルトで_emptyList()_として初期化されます。
data class Book(
var title: String,
@JsonProperty("author") var authorName: String) {
var genres: List<String>? = emptyList()
}
すべてのフィールドは、_null_または空であっても、デフォルトでシリアル化に含まれます。
@Test
fun whenSerializeBook_thenSuccess() {
val book = Book("Oliver Twist", "Charles Dickens")
val serialized = mapper.writeValueAsString(book)
val json = """
{
"title":"Oliver Twist",
"author":"Charles Dickens",
"genres":[]
}"""
assertEquals(serialized, json)
}
-
_ @ JsonInclude_アノテーションを使用して、JSONから空のフィールドを除外できます:*
@JsonInclude(JsonInclude.Include.NON_EMPTY)
data class Book(
var title: String,
@JsonProperty("author") var authorName: String) {
var genres: List<String>? = emptyList()
}
これにより、_null_、空の_Collection_、空の__Map__s、長さゼロの配列などのフィールドが除外されます。
@Test
fun givenJsonInclude_whenSerializeBook_thenEmptyFieldExcluded() {
val book = Book("Oliver Twist", "Charles Dickens")
val serialized = mapper.writeValueAsString(book)
val json = """
{
"title":"Oliver Twist",
"author":"Charles Dickens"
}"""
assertEquals(serialized, json)
}
9. 結論
この記事では、Jacksonを使用してKotlinのオブジェクトをシリアル化および逆シリアル化する方法を学びました。
_ @ JsonProperty_および_ @ JsonInclude_アノテーションの使用方法も学びました。
そして、いつものように、完全なソースコードはhttps://github.com/eugenp/tutorials/tree/master/kotlin-libraries-2[GitHubで]にあります。