gson.toJson returns an empty object for a data class

Viewed 645

I have a kotlin data class OfflineDataRequestInfo which I want to convert to Json using Gson, but it always returns an empty object

data class OfflineDataRequestInfo (
    @SerializedName("status") val status: String,
    @SerializedName("userId") val userId: String?,
    @SerializedName("fulOrderId") val fulOrderId: String,
    @SerializedName("timeStamp") val timeStamp: String,
    @SerializedName("fulOrder") val fulOrder: String,
    @SerializedName("checks") val checks: String?
)

some of the values could be null so I tried the bellow code too which returned {}

gson.toJson(OfflineDataRequestInfo("a","b","c","d", "e", "f"))

Here is a bit more info just in case that is an issue

@Entity
data class OfflineData (
    @PrimaryKey(autoGenerate = true) val id: Int = 0,
    @ColumnInfo(name="request_code") val requestCode: String?,
    @Embedded
    val requestInfoJson: OfflineDataRequestInfo
)

this is my actual function

fun postFulOurderData(offlineData: OfflineData) {
    if (offlineData != null) {
        val mainRepository = MainRepository(ApiHelper(RetrofitBuilder.apiService))
        val builder = GsonBuilder()
        builder.serializeNulls()
        val gson = builder.create()
        launch {

            val postFulOrder = mainRepository.postFulOrderOfflineData(gson.toJson(offlineData.requestInfoJson), tokenResult.access_token)
        }
    }
}

I also tried using GsonBuilder as shown above and also the default Gson, but no luck

also tried gson.toJson(offlineData.requestInfoJson, OfflineDataRequestInfo::class.java)

can any one suggest please where I am doing it wrong

your help will be very much appreciated

thanks R

3 Answers

I don't know that much about Kotlin, but I do know that you can mix Java and Kotlin pretty well, and since Gson was made with Java use in mind I think you should use Java. You can create a Java class, and then a method like this:

String toJson(OfflineDataRequestInfo o) {
    return new Gson().toJson(o, OfflineDataRequestInfo.class);
}

and then call that method from Kotlin.

I'm not saying that you should do your entire project in Java, just use Java for this one method.

Hope this helps, and please tell me if this wasn't what you had in mind :)

I just tested the following code using gson:2.2.4 and it works:

data class OfflineDataRequestInfo (
        @SerializedName("status") val status: String,
        @SerializedName("userId") val userId: String?,
        @SerializedName("fulOrderId") val fulOrderId: String,
        @SerializedName("timeStamp") val timeStamp: String,
        @SerializedName("fulOrder") val fulOrder: String,
        @SerializedName("checks") val checks: String?
)

fun main() {
    println(Gson().toJson(OfflineDataRequestInfo("a","b","c","d", "e", "f")))
}

Output: {"status":"a","userId":"b","fulOrderId":"c","timeStamp":"d","fulOrder":"e","checks":"f"}

I didn't try it on android, but it should also work. I suggest you try to update your gson version and also to write a unit test using it.

Probably you have new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create() setting for gson. If so you just need to add @Expose annotation to each field you want serialize in json:

data class OfflineDataRequestInfo (
    @Expose @SerializedName("status") val status: String,
    @Expose @SerializedName("userId") val userId: String?,
    @Expose @SerializedName("fulOrderId") val fulOrderId: String,
    @Expose @SerializedName("timeStamp") val timeStamp: String,
    @Expose @SerializedName("fulOrder") val fulOrder: String,
    @Expose @SerializedName("checks") val checks: String?
)
Related