Jackon JSON Adding deserializer module doesn't work, but annotation on class does - kotlin

I am trying to implement a custom deserializer and when I try to install it on the ObjectMapper it never gets invoked, but when I use it directly as an annotation on the class, it does. Can someone explain why and how I can actually install it on the object mapper itself?
This is never invoked
val bug = ObjectMapper().registerModule(KotlinModule.Builder().build())
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.registerModule(SimpleModule().addDeserializer(Bug::class.java, BugDeserializer()))
.readValue(bugStream, Bug::class.java)
data class Bug(
#JsonProperty("rptno")
val id: Long,
#JsonProperty("status")
#JsonDeserialize(using = StatusDeserializer::class)
val status: Status,
#JsonProperty("reported_date")
val reportedDate:Instant,
#JsonProperty("updated_date")
val updatedDate: Instant,
// val pillar: String = "",
#JsonProperty("product_id")
#JsonDeserialize(using = ProductDeserializer::class)
val product: Product,
#JsonProperty("assignee")
val assignee: String,
// val serviceRequests: List<Long> = listOf(),
#JsonProperty("subject")
val title: String,
#JsonProperty("bug_type")
val type: String
)
But, this does:
val bug = ObjectMapper().registerModule(KotlinModule.Builder().build())
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.readValue(bugStream, Bug::class.java)
#JsonDeserialize(using = BugDeserializer::class)
data class Bug(
#JsonProperty("rptno")
val id: Long,
#JsonProperty("status")
#JsonDeserialize(using = StatusDeserializer::class)
val status: Status,
#JsonProperty("reported_date")
val reportedDate:Instant,
#JsonProperty("updated_date")
val updatedDate: Instant,
// val pillar: String = "",
#JsonProperty("product_id")
#JsonDeserialize(using = ProductDeserializer::class)
val product: Product,
#JsonProperty("assignee")
val assignee: String,
// val serviceRequests: List<Long> = listOf(),
#JsonProperty("subject")
val title: String,
#JsonProperty("bug_type")
val type: String
)
```kotlin

Related

cant understand this kotlin companion object code

I went through this code example but i can't get it to run neither do understand what it does exactly.
data class Order(
val id: String,
val name: String,
val data:String
)
data class OrderResponse(
val id: String,
val name: String,
val data: String
) {
companion object {
fun Order.toOrderResponse() = OrderResponse(
id = id,
name = name,
data = data ?: "",
)
}
}
The function in the companion object extends Order with a help function to turn Order instances into OrderResponse instances. So for example like
val order = Order("a", "b", "c")
val orderResponse = order.toOrderResponse()

In Kotlin, are there graceful ways of passing values from one instance to another, which have the same name?

I have the following classes
class A(
val value1: String,
val value2: String,
val value3: String,
val value4: String,
val value5: String,
)
class B(
val value1: String,
val value2: String,
val value3: String,
val value4: String,
val value5: String,
) {
compaion object {
from(a: A) = B(
value1 = a.value1,
value2 = a.value2,
value3 = a.value3,
value4 = a.value4,
value5 = a.value5,
)
}
}
I write codes as follows when I want to create an instance of B from A
val a: A = getAFromSomewhere()
val b: B = B.from(a)
I have a lot of codes as above and It's very boring for me to write the factory method, 'from'. Is there any easy way of writing this kind of codes in Kotlin??
You might be interested in the MapStruct library.
https://mapstruct.org/
It helps map between two objects(DTO, Entity, etc..).
Code
In this example we want to map between a Person (Model) and a PersonDto (DTO).
data class Person(var firstName: String?, var lastName: String?, var phoneNumber: String?, var birthdate: LocalDate?)
data class PersonDto(var firstName: String?, var lastName: String?, var phone: String?, var birthdate: LocalDate?)
The MapStruct converter:
#Mapper
interface PersonConverter {
#Mapping(source = "phoneNumber", target = "phone")
fun convertToDto(person: Person) : PersonDto
#InheritInverseConfiguration
fun convertToModel(personDto: PersonDto) : Person
}
Usage:
val converter = Mappers.getMapper(PersonConverter::class.java) // or PersonConverterImpl()
val person = Person("Samuel", "Jackson", "0123 334466", LocalDate.of(1948, 12, 21))
val personDto = converter.convertToDto(person)
println(personDto)
val personModel = converter.convertToModel(personDto)
println(personModel)
From: https://github.com/mapstruct/mapstruct-examples/tree/master/mapstruct-kotlin

Create customise Data class model using Kotlin Koin

I'm new to Kotlin & understanding the concepts as I move. Stuck in creating one type of Data class model where the response json structure as shown below
data class SPLPlayer(
#field:Json(name ="id") val playerId: String?,
val type: String?,
#field:Json(name ="value") val currentValue: String?,
#field:Json(name ="Confirm_XI") val isIn_XI: Boolean = false,
#field:Json(name ="Matches") val totalMatchs: String?,
#field:Json(name ="Position") val position: String?,
#field:Json(name ="Skill") val skill: String?,
#field:Json(name ="skill_name") val skillName: String?,
val teamId: String?,
val name: String?, // other keys to refer Name_Full, short_name
#field:Json(name ="Bowling") val bowler: SPLBowler? = null,
#field:Json(name ="Batting") val batsmen: SPLBatsmen? = null
)
data class SPLTeamInfo (
**How to parse the Team object which is dictionary**
)
Thanks & appreciate to every reader. Looking forward for the solution.
You should be able to use your own deserializer by adding annotation to a setter #set:JsonDeserialize() and passing your own deserializer implementation.
along the lines of:
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
import com.fasterxml.jackson.databind.JsonDeserializer
.. rest of imports
// for a given simplified json string
val json: String = """{"teams":{"1":{"name":"foo"},"2":{"name":"bar"}}}"""
class MyDeserializer : JsonDeserializer<List<Team>> {
override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): List<Team>? {
// iterate over each json element and return list of parsed teams
}
}
data class JsonResp (
#set:JsonDeserialize(using = MyDeserializer::class)
var teams: List<Team>
)
data class Team (
var id: String, // this is going to be a team key
var name: String
)
Tried GitHub search with query #set:JsonDeserialize and it shows thousands of examples.

kotlin-room figure out how to save this field

I upload information to the Book class.
tableName = "Books_name" data class Books( // #Embedded // val additional_imgs: MutableList<String>, val adult: Int, val author: String, val bookmark: Int, val chapters: MutableList<Chapter>? = null, val chapters_total: Int, // #Embedded // val comments: MutableList<Comment>, autoGenerate = true val id: Int? = null, val img: String, val lang: String, val last_activity: Int, val n_chapters: Int, val publisher: String, val rating: String, val s_title: String, val status: String, val t_title: String, // val team: Int, val writer: String, val year: String )
Book has a class Chapter
//#Entity(tableName = "Books_name")
data class Chapter(
val can_read: Boolean,
// autoGenerate = true
val id_glavs_list: Int,
val new: Boolean,
val status: String,
val title: String
)
But after adding this class, an error appears. I was looking for information, but everywhere they say that this is corrected by cleaning the project. But it does not help. EROR:
Entities and Pojos must have a usable public constructor. You can have
an empty constructor or a constructor whose parameters match the
fields (by name and type). - java.util.List

kotlin default value in data class is aways zero [duplicate]

This question already has answers here:
Gson Deserialization with Kotlin, Initializer block not called
(2 answers)
Closed 4 years ago.
I've a simple data class of User
data class User(#PrimaryKey(autoGenerate = true) val id: Long, val _id: String, val name: String, val about: String,
val phoneNumber: String, val token: String,
val lastLogin: String, val avatarUrl: String, #Embedded val location: Location,
val emailId: String, val gender: Boolean, val timestamp: Long = System.currentTimeMillis())
As you can see the last parameter is val timestamp: Long = System.currentTimeMillis()
the response comes from network using retrofit and parsed using GSON
timestamp does not comes in a response json it's just extra field I need to do some logic. The problem is that value is always 0. It should be the current time stamp
This will do the trick,
data class User(#PrimaryKey(autoGenerate = true) val id: Long, val _id: String, val name: String, val about: String,
val phoneNumber: String, val token: String,
val lastLogin: String, val avatarUrl: String, #Embedded val location: Location,
val emailId: String, val gender: Boolean) {
var timestamp: Long = System.currentTimeMillis()
get() = if(field > 0) field else {
field = System.currentTimeMillis()
field
}
}