Kotlin jackson data class

jackson-kotlin

In this tutorial, we’ll discuss the Jackson support for Kotlin.

We’ll explore how to serialize and deserialize both Objects and Collections. We’ll also make use of @JsonProperty and @JsonInclude annotations.

2. Maven Configuration

First, we need to add the jackson-module-kotlin dependency to our pom.xml:

 com.fasterxml.jackson.module jackson-module-kotlin 2.9.8 

The latest version of jackson-module-kotlin can be found on Maven Central.

3. Object Serialization

Let’s start with object serialization.

Here we have a simple data Movie class that we’ll use in our examples:

data class Movie( var name: String, var studio: String, var rating: Float? = 1f)

In order to serialize and deserialize objects, we’ll need to have an instance of ObjectMapper for Kotlin.

We can create one using jacksonObjectMapper():

import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper val mapper = jacksonObjectMapper()

Or we can create an ObjectMapper and then register KotlinModule:

import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.module.kotlin.KotlinModule val mapper = ObjectMapper().registerModule(KotlinModule())

Now that we have our mapper, let’s use it to serialize a simple Movie object.

We can serialize an object to a JSON string using the method writeValueAsString():

@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 Deserialization

Next, we’ll use our mapper to deserialize a JSON String to a Movie instance.

We’ll use the method readValue():

@Test fun whenDeserializeMovie_thenSuccess() < val json = """""" val movie: Movie = mapper.readValue(json) assertEquals(movie.name, "Endgame") assertEquals(movie.studio, "Marvel") assertEquals(movie.rating, 9.2f) >

Note that we don’t need to provide TypeReference to readValue() method; we only need to specify the variable type.

We can also specify the class type in a different way:

val movie = mapper.readValue(json)

While deserializing, if a field is missing from JSON String, the mapper will use the default value declared in our class for that field.

Here our JSON String is missing rating field, so the default value 1 was used:

@Test fun whenDeserializeMovieWithMissingValue_thenUseDefaultValue() < val json = """""" val movie: Movie = mapper.readValue(json) assertEquals(movie.name, "Endgame") assertEquals(movie.studio, "Marvel") assertEquals(movie.rating, 1f) >

5. Working with Maps

Next, we’ll see how to serialize and deserialize Maps using Jackson.

Here we’ll serialize a simple Map :

@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) >

Next, when we deserialize the map, we need to make sure to specify the key and value types:

@Test fun whenDeserializeMap_thenSuccess() < val json = """""" val aMap: Map = mapper.readValue(json) assertEquals(aMap[1], "one") assertEquals(aMap[2], "two") >

6. Working with Collections

Now, we’ll see how to serialize collections in Kotlin.

Here we have a List of movies that we want to serialize to a JSON String:

@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) >

Now when we deserialize a List, we need to provide the object type Movie – just like we did with the Map:

@Test fun whenDeserializeList_thenSuccess() < val json = """[, ]""" val movieList: List = 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. Changing a Field Name

Next, we can change a field name during serialization and deserialization using @JsonProperty annotation.

Читайте также:  Удобная среда разработки python

In this example, we’ll rename the authorName field to author for a Book data class:

data class Book( var title: String, @JsonProperty("author") var authorName: String)

Now when we serialize a Book object, author is used instead of authorName:

@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) >

The same goes for deserialization as well:

@Test fun whenDeserializeBook_thenSuccess() < val json = """""" val book: Book = mapper.readValue(json) assertEquals(book.title, "Oliver Twist") assertEquals(book.authorName, "Charles Dickens") >

8. Excluding Empty Fields

Finally, we’ll discuss how to exclude empty fields from serialization.

Let’s add a new field called genres to the Book class. This field is initialized as emptyList() by default:

data class Book( var title: String, @JsonProperty("author") var authorName: String) < var genres: List? = emptyList() >

All fields are included by default in serialization – even if they are null or empty:

@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) >

We can exclude empty fields from JSON using @JsonInclude annotation:

@JsonInclude(JsonInclude.Include.NON_EMPTY) data class Book( var title: String, @JsonProperty("author") var authorName: String) < var genres: List? = emptyList() >

That will exclude fields that are null, an empty Collection, an empty Maps, an array with zero length, and so on:

@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. Conclusion

In this article, we learned how to use Jackson to serialize and deserialize objects in Kotlin.

We also learned how to use @JsonProperty and @JsonInclude annotations.

And, as always, the full source code can be found over on GitHub.

Источник

Reading and Writing JSON in Kotlin with Jackson

In this article we’ll be taking a look at how to read and write JSON files in Kotlin, specifically, using the Jackson library.

Jackson Dependency

To utilize Jackson, we’ll want to add its jackson-module-kotlin dependency to our project. If you’re using Maven, you can simply add:

dependency> groupId>com.fasterxml.jackson.module groupId> artifactId>jackson-module-kotlin artifactId> version>2.12.1 version> dependency> 

Or, if you’re using Gradle, you can add:

implementation 'com.fasterxml.jackson.module:jackson-module-kotlin:2.12.1' 

With the dependency in place, let’s define a JSON object we’ll want to read:

< "id":101, "username":"admin", "password":"Admin123", "fullName":"Best Admin" > 

Reading a JSON Object to Kotlin Object

Let’s take a look at how we can deserialize a JSON object into a Kotlin object. Since we’ll want to convert the JSON contents into a Kotlin object, let’s define a User data class:

data class User ( val id: Int, val username: String, val password: String, val fullName: String ) 

Then, we’ll want to instantiate the object mapper, which can easily be done with:

import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper // Registering the Kotlin module with the ObjectMapper instance val mapper = jacksonObjectMapper() // JSON String val jsonString = """< "id":101, "username":"admin", "password":"Admin123", "fullName":"Best Admin" >""" 

With that done, we can pass JSON contents into our ObjectMapper methods, such as readValue() , as usual for Jackson:

// Read data from a JSON string val userFromJson = mapper.readValue(jsonString) // Or val userFromJsonWithType: User = mapper.readValue(jsonString) 

If we print the value of userFromJson we’ll see something like this:

User(id=101, username=admin, password=Admin123, fullName=Best Admin) 

The readValue() function can be used with or without the Class parameter, as you saw a little earlier with the two variables ( userFromJson and userFromJsonWithType ).

Читайте также:  Java regex not pattern

Note: Using the function without the Class parameter will materialize the type and automatically create a TypeReference for Jackson.

Writing a JSON Object From Kotlin Object

Now, let’s take a look at how we can serialize a Kotlin object into a JSON object.

We’ll use the same data class ( User ) and play a little with the features of Jackson:

val user = User(102, "test", "pass12", "Test User") val userJson = mapper.writeValueAsString(user) println(userJson) 

Here, we’ve instantiated a new instance of the User class, with a few values.

The writeValueAsString() function is our key player here and serializes any object and its fields as a String.

Let’s print the userFromJson String variable and see how it looks like:

< "id":102, "username":"test", "password":"pass12", "fullName":"Test User" > 

Writing Kotlin List to JSON Array

Oftentimes, we’re dealing with lists and arrays, rather than singular objects. Let’s take a look at how we can serialize a Kotlin List into a JSON array.

Using the same data class, we’ll create a list of User s and serialize them into a JSON array:

Free eBook: Git Essentials

Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!

val userList = mutableListOf() userList.add(User(102, "jsmith", "[email protected]", "John Smith")) userList.add(User(103, "janed", "Pass1", "Jane Doe")) val jsonArray = mapper.writeValueAsString(userList) println(jsonArray) 
[ < "id":102, "username":"jsmith", "password":"[email protected]", "fullName":"John Smith" >, < "id":103, "username":"janed", "password":"Pass1", "fullName":"Jane Doe" > ] 

Reading JSON Array to Kotlin List

Now, let’s go the other way around, and deserialize a JSON array into a Kotlin List:

val userListFromJson: List = mapper.readValue(jsonArray) println(userListFromJson) 
[User(id=102, username=test, password=pass12, fullName=Test User), User(id=103, username=user, password=Pass1, fullName=Demo User)] 

Handling JSON Bidirectional Relationships

Another common thing to encounter is bidirectional relationships. In a lot of cases, you might want to have a one-to-many or many-to-one relationship between some objects.

For this, let’s create a data class Author which can contain one or more objects of type Book and the Book can have one Author :

data class Author ( val name: String, val books: MutableList ) data class Book ( val title: String, val author: Author ) 

The Author contains a list, called books , of type Book . At the same time, the Book contains an Author instance.

Читайте также:  Sending mail using php smtp

Let’s make a few instances and try to serialize them:

val author = Author("JK Rowling", mutableListOf()) val bookOne = Book("Harry Potter 1", author) val bookTwo = Book("Harry Potter 2", author) author.books.add(bookOne) author.books.add(bookTwo) 

If we were to do the same thing as before:

val authors = mapper.writeValueAsString(author) 

We’d quickly run into an issue:

com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: Book["author"]->Author["books"]->. 

The Author contains the Book , which contains the Author , which contains the Book , which contains the Author , and so on, until a StackOverflowError is thrown.

This is thankfully, easily fixable, using the @JsonManagedReference and @JsonBackReference annotations. We let Jackson know about this bidirectional relationship, that could go on forever:

data class Author ( val name: String, @JsonManagedReference val books: MutableList ); data class Book ( val title: String, @JsonBackReference val author: Author ); 

@JsonManagedReference specifies the attribute that will be serialized normally and the @JsonBackReference will specify the attribute omitted from serialization. We’ll effectively take out the author reference from the Book when each is serialized.

Now, we can serialize the authors:

val authors = mapper.writeValueAsString(author) println(authors) 

If we run this code, it’ll produce:

< "name":"JK Rowling", "books":[ < "title":"Harry Potter 1" >, < "title":"Harry Potter 2" > ] > 

Conclusion

In this tutorial, we’ve gone over how to read and write JSON Files in Kotlin with Jackson.

We’ve gone over the required dependencies, how to serialize and deserialize JSON and Kotlin objects, as well as arrays and lists.

Finally, we’ve covered how to handle bidirectional relationships when serializing and deserializing.

Источник

Kotlin JSON to Data class — JSON Serialization with Jackson Library

In this post, we are going to learn how to convert JSON string Data class and vice versa in kotlin.

For this, we are going to use the Jackson library.

Convert JSON to Data class Kotlin

What is Data class in kotlin?

A data class is a class that only contains state and does not perform any operation.

By using this class we don’t need to write any getter() and setter() methods in the class to access the state of the class.

To Convert JSON to Data class or vice versa we need to add Jackson dependency
implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.11.+"

First, we need to create a Data class, here we are creating a class named Test

data class Test( val id:Int,val name:String )

This Data class consist of two parameters id and name

Convert Data class to JSON String

To convert the Data class to JSON string we need to apply the below code for the Test class

val jacksonMapper= jacksonObjectMapper() val jsonString=jacksonMapper.writeValueAsString(Test(1,"JackSon")) print(jsonString)

This will print below the converted JSON string

Convert JSON String to Data class

To convert JSON String to Data class we need to apply the below code

val jacksonMapper= jacksonObjectMapper() val testObject=jacksonMapper.readValue("",Test::class.java) print("Test style="font-family:Georgia,serif"> >

this will print below the output

In this post, we learned how to convert JSON string to Data class and vice versa in Kotlin with Jackson library

Источник

Оцените статью