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.