https://kotlinlang.org logo
#serialization
Title
# serialization
j

jakiej

11/02/2018, 12:10 AM
Hi, I am trying to maintain some backward compatibility to serialized JSON: for example
Copy code
{
  "a": {
    "b": "c"
  }
}
to
Copy code
@Serializable
class Wrapper(val a: Map<String, Any> = mapOf())
what's the easiest way? (if there a way I can specify default (e.g,
LinkedHashMap
) for Map and default (
String
) for "c"?
s

sandwwraith

11/02/2018, 11:44 AM
I haven't understood question completely, are you implying
class Wrapper(val a: Map<String, Any> = linkedMapOf("b" to "c"))
?
j

jakiej

11/02/2018, 3:40 PM
Sorry for the confusion. The root question is how to deserialize
{ "a": { "b": "c" }}
to
Wrapper
with ease. The default (de)serializer assumes type information is also present:
{ "a": { "b": ["kotlin.String", "c"] }}
.
s

sandwwraith

11/02/2018, 8:37 PM
That's because you have
Any
as type parameter. Can you replace it with
String
?
j

jakiej

11/03/2018, 5:02 AM
Thanks. Yes, I understand that. Unfortunately no, it's indeed
Any
. could be a
String
, another
Map
or a
List
.
Another finding is that
@Serializable class Wrapper(val a: Map<String, CharSequence> = mapOf())
will serialize to
{ "a": { "b": "c" }}
too, but deserialization does not work either.
s

sandwwraith

11/06/2018, 9:14 AM
Since you have no types known in advance, you can probably resort to using
JsonTreeMapper
to parse untyped structure to a generic json tree
j

jakiej

11/06/2018, 4:49 PM
In the real case, the Wrapper class is much more complicated. I minimized it to only show the problematic part. So
JsonTreeMapper
is not really a choice, and I really need to deserialize the JSON into its binding. Is there a way to specify a default type for certain JSON node?
Also, is the latter case by design? By default, kotlinx.serialization can only serialize certain object to JSON, but can't not deserialize the JSON produced by itself to the same object?
s

sandwwraith

11/07/2018, 4:17 PM
It can do it, but for it it should save objects with type information. By default, it will save your map like this:
{ "a": { "b": ["kotlin.String", "c"] }}
. So the problem here is only when you're integrating with other JSON forms of type recording. Deserializing values into
Any
without type information is indeed prohibited by design: kotlinx.serialization has pull model, where you first determine the type, then look into the input stream, and if the type mismatches, it's an error.
j

jakiej

11/07/2018, 5:36 PM
By default, I meant any
@Serializable class Wrapper(val a: Map<String, java.io.Serializable>)
can be serialized to a JSON string, but the same JSON string can NOT be deserialized.
@sandwwraith sorry for the @, but what's the suggested solutions? for a serializable class with fields like this
a: Map<String, java.io.Serializable>
s

sandwwraith

11/12/2018, 5:07 PM
I don't see how
java.io.Serializable
related
j

jakiej

11/12/2018, 5:12 PM
My original class has a field
a: Map<String, java.io.Serializable>
(or it can be relaxed to
a: Map<String, Any>
). with
java.io.Serializable
, this field can be serialized to
"a": { "b": "c" }
, but can't be deserialized. with
Any
, it can be deserialized, but the serialization has type info (`"a": { "b": [String, "c"] }) with is not backward compatible.
9 Views