Generic jsonObjectparsing using gson - kotlin

Hi there im trying to make a generic client and trying to parse the json to a object.
gson?.fromJson(khttpResponse.jsonObject.toString(),
UserInfo::class.java)
works.
val listType = object : TypeToken<T>() {}.type
gson?.fromJson(khttpResponse.jsonObject.toString(), listType)
Doesnt't work. So my question is there a workaround to to parse json in gson or do you guys use some other libary?
UserInfo:
open class UserInfo (
val profileId: String,
val code: String,
val message: String,
val path: String,
val profile: Profile,
val errorDetail: Any
)
data class Profile(
val firstname: String,
val lastname: String
)

Related

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

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

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

How do I get context inside a companion object that is inside a data class Kotlin?

I'm trying to use a resource string inside a companion object that is inside a data class. but I don't Know how to obtain context in that case in Kotlin.
Anyone knows how to do it?
data class PhoneCall(
val type: String,
val code: String,
val description: String){
companion object{
const val SOLUTION_NO_SOLUTION = "NO_SOLUTION"
const val SOLUTION_TOMORROW = "71_INAT"
const val SOLUTION_TODAY = "72_INAT"
val solutions = listOf(
PhoneCall(Service.Traffic.PICK_UP, SOLUTION_NO_SOLUTION, Resources.getSystem().getString(R.string.makeService))
)
}
I need to use a resource string in the 3 parameter, but I'm not able to get the context.
You can modify you PhoneCall model to store a string resource id instead of the actual string.
data class PhoneCall(
val type: String,
val code: String,
#StringRes val description: Int
) {
companion object {
const val SOLUTION_NO_SOLUTION = "NO_SOLUTION"
const val SOLUTION_TOMORROW = "71_INAT"
const val SOLUTION_TODAY = "72_INAT"
val solutions = listOf(
PhoneCall(Service.Traffic.PICK_UP, SOLUTION_NO_SOLUTION, R.string.makeService)
)
}
}
Then, when you need to display this data in the UI (say a TextView), you can fetch the string from the resource id.
descriptionTextView.text = getString(phoneCall.description)

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.

Transform data class to map kotlin

My problem is that I need to transform a data class in kotlin to a map, because I need to work with this structure as a requirement, because this response will be used for a groovy classes and there is a post-process where there are validations iterations etc, with this map. My data class is the next (Podcast):
data class PodCast(val id: String, val type: String, val items: List<Item>, val header: Header, val cellType:String? = "")
data class Item(val type: String, val parentId: String, val parentType: String, val id: String, val action: Action, val isNew: Boolean)
data class Header(val color: String, val label: String)
data class Action(val type: String, val url: String)
I made the transformation manually, but I need a more sophisticated way to achieve this task.
Thanks.
You can also do this with Gson, by serializing the data class to json, and then deserializing the json to a map. Conversion in both directions shown here:
val gson = Gson()
//convert a data class to a map
fun <T> T.serializeToMap(): Map<String, Any> {
return convert()
}
//convert a map to a data class
inline fun <reified T> Map<String, Any>.toDataClass(): T {
return convert()
}
//convert an object of type I to type O
inline fun <I, reified O> I.convert(): O {
val json = gson.toJson(this)
return gson.fromJson(json, object : TypeToken<O>() {}.type)
}
See similar question here
I have done this very simple. I got the properties of the object, just using the .properties groovy method, which gave me the object as a map.