Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serialize string property as json object #2072

Closed
ArtemMikhaylov opened this issue Oct 24, 2022 · 4 comments
Closed

Serialize string property as json object #2072

ArtemMikhaylov opened this issue Oct 24, 2022 · 4 comments
Labels

Comments

@ArtemMikhaylov
Copy link

What is your use-case and why do you need this feature?
I have a class like that

data class MyClass2(
    var id: Long,
    var name: String,
    var jsonData: String? = null
)

Property jsonData for saving json object as string, jsonData can be any json object with different contents

When sending class to server, I want to have MyClass2 mapped to json like this:

{
    "id":7,
    "name":"Steve",
    "jsonData":{
         "someField1":true,
         "someField2":4,
         ...
    }
}

I can't figure out how to achieve this. I was able to do other way around: deserialize json object field to my class string property. But struggle with serialization.

Describe the solution you'd like

In GSON I used to achieve this by making JsonStringFieldAdapter and annotation on property:

@JsonAdapter(JsonStringFieldAdapter::class)
var jsonData: String? = null
public class JsonStringFieldAdapter implements JsonSerializer<String>, JsonDeserializer<String> {

    @Override
    public String deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        return json.toString();
    }

    @Override
    public JsonElement serialize(String src, Type typeOfSrc, JsonSerializationContext context) {
        return JsonParser.parseString(src).getAsJsonObject();
    }
}

I tried to make something similar with kotlinx.serialization

@Serializable(with = JsonAsStringSerializer::class)
var jsonData: String? = null
object JsonAsStringSerializer: JsonTransformingSerializer<String>(tSerializer = String.serializer()) {
    override fun transformDeserialize(element: JsonElement): JsonElement {
        return JsonPrimitive(value = element.toString())
    }

    override fun transformSerialize(element: JsonElement): JsonElement {
        return super.transformSerialize(element)
    }
}

Deserialization seems to be working, but I can't figure out how to do serialization

@ArtemMikhaylov
Copy link
Author

ArtemMikhaylov commented Oct 24, 2022

Well, I could make it work, but in not very nice way. Maybe there's a nicer option? And if there's not, it would be cool to have something like in GSON (example above).

That's how I made it work:

    override fun transformSerialize(element: JsonElement): JsonElement {
        return Json.decodeFromString<JsonObject>(
            element.toString()
                .replace("\\", "")
                .removePrefix("\"").removeSuffix("\"")
        )
    }

It looks like JsonElement representing String passed to transformSerialize , and it is already with slashes all around. It would be more flexible if during serialization we could map actual data type (in this case String) to desired JsonElement, and not dealing with already mapped JsonElement to transform it to our's needs.

@aSemy
Copy link
Contributor

aSemy commented Oct 24, 2022

This might be helped by a new feature that is yet to be released #2041, which would allow encoding a string directly, without surrounding it in quotes.

@sandwwraith
Copy link
Member

Yes, I think #2041 in the new release would be a way to go. Alternatively, you can write a basic custom serializer (without using JsonTransformingSerializer) — String should be unquoted here.

@sandwwraith
Copy link
Member

Actually, even with #2041 you still would need to write a basic serializer. JsonElement in JsonTransformingSerializer will always be quoted

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants