3

I have created a sealed class for the json field Value under CustomAttribute data class. This field can return String or Array of Strings.

How can we deserialize this sealed class from json?

data class CustomAttribute (
     val attributeCode: String,
     val value: Value 
)

sealed class Value {
      class StringArrayValue(val value: List<String>) : Value()
      class StringValue(val value: String)            : Value()
}
Akash Bisariya
  • 2,777
  • 1
  • 28
  • 40
  • Can i ask why do you need a value parameter that can be or a list or a single string value? I asked because im curios not to critizied, btw can this help or you already look at it? https://github.com/Kotlin/kotlinx.serialization/issues/103 – Dak28 Feb 17 '20 at 11:45
  • @Dak28 It was required as the API can return any of these values at a time. Thanks for the link but I still not able to solve this, can you please help in this.. – Akash Bisariya Feb 17 '20 at 15:49

2 Answers2

1

One solution is to use a RuntimeTypeAdapterFactory as per the instructions in this answer

val valueTypeAdapter = RuntimeTypeAdapter.of(Value::class.java)
    .registerSubtype(StringArrayValue::class.java)
    .registerSubtype(StringValue::class.java)
val gson = GsonBuilder().registerTypeAdapter(valueTypeAdapter).create()

RuntimeTypeAdapter is included in the source code for Gson but not exposed as a Maven artifact.

It is designed to be copy/pasted into your project from here

David Rawson
  • 19,162
  • 6
  • 83
  • 120
-1

I have successfully serialized and de-serialized a sealed class in the past, with a disclaimer of using Jackson, not Gson as my serialization engine.

My sealed class has been defined as:

@JsonTypeInfo(use = JsonTypeInfo.Id.MINIMAL_CLASS, include = JsonTypeInfo.As.PROPERTY, visible = true)
sealed class FlexibleResponseModel
    class SnapshotResponse(val collection: List<EntityModel>): FlexibleResponseModel()
    class DifferentialResponse(val collection: List<EntityModel>): FlexibleResponseModel()
    class EventDrivenResponse(val collection: List<EntityEventModel>): FlexibleResponseModel()
    class ErrorResponse(val error: String): FlexibleResponseModel()

With the annotations used, it required no further configuration for the Jackson instance to properly serialize and de-serialize instances of this sealed class granted that both sides of the communication possessed a uniform definition of the sealed class.

While I recognise that JsonTypeInfo is a Jackson-specific annotation, perhaps you might consider switching over from Gson if this feature is a must - or you might be able to find an equivalent configuration for Gson which would also include the class identifier in your serialized data.

ryfterek
  • 544
  • 4
  • 16