Kotlin Data Class da Json utilizzando GSON


105

Ho una classe POJO Java come questa:

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

e ho una classe di dati Kotlin come questa

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

Come fornire json keya tutte le variabili kotlin data classcome l' @SerializedNameannotazione nelle variabili java?


1
Come hai fatto in Java? Mostra un esempio.
nhaarman

Cos'è un selettore json?
voddan

@voddan quello che intendevo con quei selettori json è che le stringhe che posso usare per selezionare un particolare oggetto / array json: nel mio caso "topic", "id", "image". Spero di averti chiarito. Grazie :)
erluxman

@nhaarman Ho modificato la domanda, spero che sia quello che intendi
erluxman

Risposte:


227

Classe di dati:

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

a JSON:

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

da JSON:

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

36
Utilizza le annotazioni solo in caso di mancata corrispondenza del nome della variabile. Altrimenti, sì, non necessario
Vik

3
A mio parere, le annotazioni ci consentono di avere classi che una volta serializzate possono essere escluse o includere le variabili. Molto utile se utilizzato con retrofit. Ciò non invia spazzatura al server. Inoltre, quando ci sono cambiamenti nei nomi delle variabili sul lato server, è più doloroso cambiarli direttamente nella variabile di classe che nell'annotazione.
Deneb Chorny

11
@Vik una cosa da notare è che i nomi delle tue variabili possono essere offuscati (come in un'app Android) ma l'annotazione rimarrà intatta
Caleb_Allen

@AntonGolovin Non sono in grado di passare la mia classe di dati dal metodo Json.Devo dichiarare la mia classe di dati all'interno del file java?
Ravi Yadav

Se lo fai, credo che perderai il formato JSON che potrebbe causare IllegalStateException lungo la strada
portfoliobuilder

19

Basato sulla risposta di Anton Golovin

Dettagli

  • Versione Gson: 2.8.5
  • Android Studio 3.1.4
  • Versione Kotlin: 1.2.60

Soluzione

Crea qualsiasi dato di classe ed eredita l' interfaccia JSONConvertable

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

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

Utilizzo

Classe di dati

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

Da JSON

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

A JSON

val json = object.toJSON()

Perché usi l' SerializedNameannotazione invece della strategia di denominazione dei campi, Vasily?
peterchaula

2
@Peter perché @SerializedNamemi consentirà di utilizzare nomi personalizzati delle variabili che potrebbero non corrispondere alla chiave json. E sì, potresti non usarlo @SerializedNamese non ne hai bisogno.
Vasily Bodnarchuk

2

Puoi usare simili nella classe 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 anche per la classe annidata puoi usare lo stesso come se ci fosse un oggetto annidato. Fornisci solo il nome Serialize per la classe.

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

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

}

quindi se ottieni risposta dal server ogni chiave verrà mappata con JOSN.

Alos, converti List in JSON:

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

ndroid converte da JSON a Object:

val json = getJson()
val topic = gson.fromJson(json, Topic::class.java)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.