Classe de dados Kotlin da Json usando GSON

105

Eu tenho classe POJO Java como esta:

class Topic {
    @SerializedName("id")
    long id;
    @SerializedName("name")
    String name;
}

e eu tenho uma classe de dados Kotlin como esta

 data class Topic(val id: Long, val name: String)

Como fornecer o json keypara quaisquer variáveis ​​do mesmo kotlin data classtipo a @SerializedNameanotação em variáveis ​​java?

Erluxman
fonte
1
Como você fez isso em Java? Mostre um exemplo.
nhaarman
O que é um seletor json?
voddan
@voddan o que quero dizer com seletor json é que strings que posso usar para selecionar um objeto / array json particular: no meu caso, "tópico", "id", "imagem". Espero ter deixado isso claro para você. Obrigado :)
erluxman
@nhaarman Eu editei a pergunta, espero que seja isso que você quer dizer
erluxman

Respostas:

227

Classe de dados:

data class Topic(
  @SerializedName("id") val id: Long, 
  @SerializedName("name") val name: String, 
  @SerializedName("image") val image: String,
  @SerializedName("description") val description: String
)

para JSON:

val gson = Gson()
val json = gson.toJson(topic)

de JSON:

val json = getJson()
val topic = gson.fromJson(json, Topic::class.java)
Anton Holovin
fonte
36
Use anotações apenas quando houver uma incompatibilidade de nome de variável. Caso contrário, sim, não é necessário
Vik
3
Na minha opinião, as anotações nos permitem ter classes que quando serializadas podem ser excluídas ou incluir as variáveis. Muito útil quando usado com retrofit. Isso não envia lixo para o servidor. Além disso, quando há mudanças nos nomes das variáveis ​​no lado do servidor, é mais doloroso alterá-las diretamente na variável de classe do que na anotação.
Deneb Chorny
11
@Vik, uma coisa a se observar é que os nomes das variáveis ​​podem ser ofuscados (como em um aplicativo Android), mas a anotação permanecerá intacta
Caleb_Allen
@AntonGolovin Não consigo passar minha classe de dados do método Json. Preciso declarar minha classe de dados dentro do arquivo java?
Ravi Yadav de
Se você fizer isso, acredito que perderá o formato JSON, o que pode causar IllegalStateException no futuro
portfólio de
19

Baseado na resposta de Anton Golovin

Detalhes

  • Versão Gson: 2.8.5
  • Android Studio 3.1.4
  • Versão Kotlin: 1.2.60

Solução

Crie quaisquer dados de classe e herde a interface JSONConvertable

interface JSONConvertable {
     fun toJSON(): String = Gson().toJson(this)
}

inline fun <reified T: JSONConvertable> String.toObject(): T = Gson().fromJson(this, T::class.java)

Uso

Classe de dados

data class User(
    @SerializedName("id") val id: Int,
    @SerializedName("email") val email: String,
    @SerializedName("authentication_token") val authenticationToken: String) : JSONConvertable

De JSON

val json = "..."
val object = json.toObject<User>()

Para JSON

val json = object.toJSON()
Vasily Bodnarchuk
fonte
Por que você usa a SerializedNameanotação em vez da estratégia de nomenclatura de campo, Vasily?
peterchaula de
2
@Peter porque @SerializedNameme permite usar nomes personalizados das variáveis ​​que podem não corresponder à chave json. E sim, você não pode usar @SerializedNamese não precisar.
Vasily Bodnarchuk de
2

Você pode usar algo semelhante na aula de Kotlin

class InventoryMoveRequest {
    @SerializedName("userEntryStartDate")
    @Expose
    var userEntryStartDate: String? = null
    @SerializedName("userEntryEndDate")
    @Expose
    var userEntryEndDate: String? = null
    @SerializedName("location")
    @Expose
    var location: Location? = null
    @SerializedName("containers")
    @Expose
    var containers: Containers? = null
}

E também para a classe aninhada, você pode usar o mesmo como se houvesse um objeto aninhado. Basta fornecer o nome serializar para a classe.

@Entity(tableName = "location")
class Location {

    @SerializedName("rows")
    var rows: List<Row>? = null
    @SerializedName("totalRows")
    var totalRows: Long? = null

}

então, se obtiver uma resposta do servidor, cada chave será mapeada com JOSN.

Alos, converta lista em JSON:

val gson = Gson()
val json = gson.toJson(topic)

ndroid converter de JSON para objeto:

val json = getJson()
val topic = gson.fromJson(json, Topic::class.java)
Pawan Soni
fonte