Gson does not map values in Java - java

I get this result from an API:
{"sessionID":"","randomKey":"","id":0,"userName":"","useIPAddress":"","usePortNo":"","response":{"code":-24,"message":"Incorrect credential","postedDateTime":null,"accountNo":0,"trxnNo":0,"changeTypeID":0}}
and my class is this:
class ResponseLoginParam {
val RandomKey: String? = null
val SessionID: String? = null
val UseIPAddress: String? = null
val UsePortNo: Int? = null
val UserName: String? = null
val Response: Response? = Response()
}
class Response {
val Code: Int? = null
val Message: String? = null
val PostedDateTime: String? = null
val AccountNo: Int? = null
val ChangeTypeID: Int? = null
}
for some reason it does not map to my object. But if I get the result like this:
{"SessionID":"","RandomKey":"","Id":0,"UserName":"","UseIPAddress":"","UsePortNo":"","Response":{"Code":-24,"Message":"Incorrect credential","PostedDateTime":null,"AccountNo":0,"TrxnNo":0,"ChangeTypeID":0}}
It is now capitalized, I can map the values properly. Why is this?

You need to either name class and json fields equally, or define serialization name:
class Response {
#SerializedName("code") // since its "code" in json
val Code: Int? = null
//no need for annotation because class field name equals json field name
val message: String? = null
}

Related

MapStruct using default constructor over parameterised constructor of Kotlin data class(error: constructor in class cannot be applied to given types)

In my Micronaut Kotlin project I have two repositories. I am using MapStruct in both of them.
Source Class
#JsonInclude
data class Source(
var id: String,
var no: String,
var value: String,
)
Destination Class
#JsonInclude
data class Destination(
var id: String,
var no: String,
var value: String,
)
Mapper
#Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE)
interface SourceMapper {
fun convertToDestination(doc: Source): Destination
}
One of them first extracted the values of source class attributes and then passes these values to the parameterised constructor generated by kotlin data class
public Destination convertToDestination(Source doc){
if ( doc = = null ) {
return null;
}
String id = null;
String no = null;
String value = null;
id = doc.getId();
no = doc.getNo();
value= doc.getValue();
Destination d = new Destination(id, no,value);
}
Another one first creates the object then uses setter to assign value which fails at compile time as default constructor is not present for the data class.
public Destination convertToDestination(Source doc)
{
if ( doc == null ) {
return null;
}
Destination d = new Destination();
d.setId(doc.getId());
d.setNo(doc.getNo());
d.setValue(doc.getValue());
return d;
}
I have compared both the Gradle files and I am using same version of mapstruct.
```kapt("org.mapstruct:mapstruct-processor:1.5.0.RC1")``` and ```implementation("org.mapstruct:mapstruct:1.5.0.RC1")```
Please help me understand the behaviour and how we can control it.

How to deserialize nested class with Gson in Kotlin?

I have json as in below, I'm really new on kotlin and i tried all examples but cannot set my nested class values when i convert to json
Here my json
{"Init":{"MOP":[{"Id":"1","Type":"0","ProtocolVersion":"1.0","MopCode":"*NEXB","TerminalId":"'P400Plus-275008565'","IP":"'192.168.1.15'","Currency":"EUR"},{"Id":"2","Type":"0","ProtocolVersion":"1.0","MopCode":"*NEXF","TerminalId":"'P400Plus-275008565'","IP":"'10.0.0.0:901'","Currency":"EUR"}]}}
Here my POJO
class Root {
#JsonProperty("Init")
var init: Init? = null
}
class MOP {
#JsonProperty("Id")
var id: String? = null
#JsonProperty("Type")
var type: String? = null
#JsonProperty("ProtocolVersion")
var protocolVersion: String? = null
#JsonProperty("MopCode")
var mopCode: String? = null
#JsonProperty("TerminalId")
var terminalId: String? = null
#JsonProperty("IP")
var ip: String? = null
#JsonProperty("Currency")
var currency: String? = null
}
class Init {
#JsonProperty("MOP")
var mop: List<MOP>? = null
}
Here my trial
val root: TestClass.Root = gson.fromJson(receiveString,TestClass.Root::class.java)
val initList = HashMap<String?,String?>()
if (root.init != null){
val mopList = root.init!!.mop
if (mopList != null) {
for (item in mopList){
initList.put(item.mopCode,item.id)
}
}
}
Always root.init and root.init.mop are null
What you can suggest me?
Thanks
Your Json construction has different tree.
You should use following structure:
data class Root (
#SerializedName("Init") val init : Init
)
data class Init (
#SerializedName("MOP") val mOP : List<MOP>
)
data class MOP (
#SerializedName("Id") val id : Int,
#SerializedName("Type") val type : Int,
#SerializedName("ProtocolVersion") val protocolVersion : Double,
#SerializedName("MopCode") val mopCode : String,
#SerializedName("TerminalId") val terminalId : String,
#SerializedName("IP") val iP : String,
#SerializedName("Currency") val currency : String
)
And you can parse just with:
Gson().fromJson(data,Root::class.java)
Also if you are using Gson, you should use SerializedName instead JsonProperty.

getDeclaredMethod in Kotlin?

I have a question about "getDeclaredMethod" in kotlin.
I have a class:
class WorksheetFreeField : Serializable {
#SerializedName("val_value_1")
var val_value_1: String? = ""
#SerializedName("val_value_2")
var val_value_2: String? = ""
#SerializedName("val_value_3")
var val_value_3: String? = ""
Now I try this:
try {
val c = WorksheetFreeField::class
for (field in fields) {
val method = c.java.getDeclaredMethod("setVal_value_" + field.order)
Now I got this error in my catch:
com.werkbon.objects.WorksheetFreeField.setVal_value_1 []
What did I do wrong?
Take a look at c.java.declaredMethods in debug mode. Method setVal_value_1 exists, but has a parameter of type String.
So to make c.java.getDeclaredMethod work, you have to call it with 2 parameters: method name and String::class.java.

Issue while using kotlin reflaction to map object member properties to hashmap

open class Test {
fun getAsHashMap() : HashMap<String, Any> {
val hashMap = HashMap<String, Any>()
val className = this.javaClass.kotlin
for (prop in className::class.memberProperties) {
val field = className::class.java.getDeclaredField(prop.name)
val fieldSerializedName : SerializedName? = field.getAnnotation(SerializedName::class.java)
fieldSerializedName?.let {
hashMap[fieldSerializedName.value] = prop.get(this)!!
} ?: run {
hashMap[prop.name] = prop.get(this)!!
}
}
return hashMap
}
}
I have wrote above function to map the memberProperties of object instance of its child class to hashmap. It either uses serialized name of the member or prop name [Based on availability of serialized name for that property]
But unfortunately I get the following error.
This is my first time using reflection java/kotlin, please let me know if it can be fixed.
Edit 1:
It works perfectly if I use name of the this.javaClass.kotlin directly like this
data class ProductInformation (
#field:SerializedName("productid")
val productId: Int,
#field:SerializedName("productname")
val productName: String,
#field:SerializedName("brandname")
val brandName: String,
#field:SerializedName("originalprice")
val originalPrice: Int,
#field:SerializedName("sellingprice")
val sellingPrice: Int,
#field:SerializedName("productgender")
val productGender: String,
#field:SerializedName("productvariant")
val productVariant: String,
#field:SerializedName("discounted")
val discounted: String,
#field:SerializedName("productcategory")
val productCategory: String
) : StructuredEventAttribute {
override fun getAsHashMap(): HashMap<String, Any> {
val hashMap = HashMap<String, Any>()
for (prop in ProductInformation::class.memberProperties) {
val field = ProductInformation::class.java.getDeclaredField(prop.name)
val fieldSerializedName : SerializedName? = field.getAnnotation(SerializedName::class.java)
fieldSerializedName?.let {
hashMap[fieldSerializedName.value] = prop.get(this)!!
} ?: run {
hashMap[prop.name] = prop.get(this)!!
}
}
return hashMap
}
}
interface StructuredEventAttribute {
fun getAsHashMap() : HashMap<String, Any>
}
It works perfectly fine
ProductInformation::class.memberProperties returns a collection of ProductInformation class member properties.
className::class.memberProperties (where className = this.javaClass.kotlin) returns a collection of member properties of class of className, which is KClass<out Test>. In short you are getting members of KClass instead of Test.
Solution: change className::class.memberProperties to className.memberProperties.

Convert a Map to an Object in Kotlin

Hello guys I have a simple question ,
I have a Map full of element and I want to convert It in my Object , let me show you some code :
Here is my Object :
class Bundle(map: Map<String, Any>) {
var version: String?
var app: String?
var countries: ArrayList<Any>?
var currency: ArrayList<Any>?
var force: Boolean?
var name: String?
var service: ArrayList<Any>?
var money: Int?
init {
version= null
app= null
countries= arrayListOf()
currency= arrayListOf<Any>()
force= true
name = ""
service= arrayListOf<Any>()
money= 0
}
}
And there is the Map that i want to convert:
fun getBundle() {
var db = FirebaseFirestore.getInstance()
val docRef = db.collection("aa").document("bb")
docRef.get().addOnCompleteListener { task ->
if (task.isSuccessful) {
val document = task.result
if (document.exists()) {
Log.d("Doc", "DocumentSnapshot data: " + document.data!!)
// Here i want to take (document.data!!) and convert it to my Bundle class
} else {
Log.d("NO doc", "No such document")
}
} else {
Log.d("ERROR", "get failed with ", task.exception)
}
}
}
Thank you !
Ok I found the solution
I transformed my Bundle class in a data class :
data class Bundle(
var version: String? = null,
var app: String? = null,
var countries: ArrayList<Any> = arrayListOf(),
var currency: HashMap<String, Any> = hashMapOf(),
var force: Boolean = false,
var name: String? = null,
var service: ArrayList<Any> = arrayListOf(),
var money: Int = 0
)
And then I simply added this on my method , where I want to convert my Map to my Bundle Object :
val myObject = document.toObject(Bundle::class.java)

Categories