У меня есть запечатанный класс WebSocketMessage
, у которого есть несколько подклассов. WebSocketMessage
имеет поле с именем type
, которое используется для различения подклассов.
Все подклассы имеют свое собственное поле с именем payload
, которое имеет разный тип для каждого подкласса.
В настоящее время я использую PolymorphicJsonAdapterFactory
от Moshi, чтобы эти классы можно было анализировать из JSON и кодировать в JSON.
Это все работает, но мне нужно закодировать поле payload
в строковый JSON вместо объекта JSON.
Есть ли возможность написать собственный класс адаптера, чтобы помочь мне с этой проблемой? Или есть какое-то другое решение, чтобы мне не пришлось выполнять эту последовательность вручную?
Я пытался найти пользовательские адаптеры, но не могу найти, как передать экземпляр moshi в адаптер, чтобы я мог закодировать данное поле в JSON и затем его преобразовать в строку, а также я не нашел ничего другого, что могло бы мне помочь.
Класс WebSocketMessage
с его подклассами:
sealed class WebSocketMessage(
val type: Type
) {
enum class Type(val type: String) {
AUTH("AUTH"),
PING("PING"),
FLOW_INITIALIZATION("FLOW_INITIALIZATION")
}
class Ping : WebSocketMessage(Type.PING)
class InitFlow(payload: InitFlowMessage) : WebSocketMessage(Type.FLOW_INITIALIZATION)
class Auth(payload: Token) : WebSocketMessage(Type.AUTH)
}
Экземпляр Моши с PolymorphicJsonAdapterFactory
:
val moshi = Moshi.Builder().add(
PolymorphicJsonAdapterFactory.of(WebSocketMessage::class.java, "type")
.withSubtype(WebSocketMessage.Ping::class.java, WebSocketMessage.Type.PING.type)
.withSubtype(
WebSocketMessage.InitFlow::class.java,
WebSocketMessage.Type.FLOW_INITIALIZATION.type
)
.withSubtype(WebSocketMessage.Auth::class.java, WebSocketMessage.Type.AUTH.type)
)
// Must be added last
.add(KotlinJsonAdapterFactory())
.build()
Как я кодирую в JSON:
moshi.adapter(WebSocketMessage::class.java).toJson(WebSocketMessage.Auth(fetchToken()))
В настоящее время я получаю JSON в следующем формате:
{
"type":"AUTH",
"payload":{
"jwt":"some_token"
}
}
Что бы я хотел получить:
{
"type":"AUTH",
"payload":"{\"jwt\":\"some_token\"}"
}
Во втором примере полезная нагрузка - это строковый объект JSON, который как раз то, что мне нужно.