Kotlin Data Class von Json mit GSON

103

Ich habe Java POJO Klasse wie folgt:

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

und ich habe eine Kotlin-Datenklasse wie diese

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

Wie json keykann man Variablen kotlin data classwie der @SerializedNameAnnotation in Java-Variablen zur Verfügung stellen?

Erluxman
quelle
1
Wie hast du das in Java gemacht? Zeigen Sie ein Beispiel.
Nhaarman
Was ist ein JSON-Selektor?
Voddan
@voddan Was ich mit diesen JSON-Selektoren gemeint habe, sind die Zeichenfolgen, mit denen ich ein bestimmtes JSON-Objekt / Array auswählen kann: in meinem Fall "Thema", "ID", "Bild". Ich hoffe, ich habe es dir klar gemacht. Danke :)
Erluxman
@nhaarman Ich habe die Frage bearbeitet, ich hoffe das ist was du meinst
Erluxman

Antworten:

223

Datenklasse:

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

an JSON:

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

von JSON:

val json = getJson()
val topic = gson.fromJson(json, Topic::class.java)
Anton Holovin
quelle
35
Verwenden Sie Anmerkungen nur, wenn ein Variablenname nicht übereinstimmt. Ansonsten ja, nicht nötig
Vik
3
Meiner Meinung nach erlauben uns die Anmerkungen Klassen, die bei der Serialisierung ausgeschlossen werden können oder die Variablen enthalten. Sehr nützlich bei Nachrüstung. Dadurch wird kein Müll an den Server gesendet. Wenn sich die Namen der Variablen auf der Serverseite ändern, ist es schmerzhafter, sie direkt in der Klassenvariablen als in der Anmerkung zu ändern.
Deneb Chorny
10
@ Vik eine Sache zu beachten ist, dass Ihre Variablennamen möglicherweise verschleiert werden können (wie in einer Android-App), aber die Anmerkung bleibt intakt
Caleb_Allen
@AntonGolovin Ich kann meine Datenklasse nicht von der Json-Methode übergeben. Muss ich meine Datenklasse in einer Java-Datei deklarieren?
Ravi Yadav
Wenn Sie dies tun, werden Sie wahrscheinlich das JSON-Format verlieren, was später zu IllegalStateException führen kann
portfoliobuilder
18

Basierend auf der Antwort von Anton Golovin

Einzelheiten

  • Gson-Version: 2.8.5
  • Android Studio 3.1.4
  • Kotlin-Version: 1.2.60

Lösung

Erstellen Sie alle Klassendaten und erben Sie die JSONConvertable- Schnittstelle

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

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

Verwendung

Datenklasse

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

Von JSON

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

Zu JSON

val json = object.toJSON()
Wassili Bodnarchuk
quelle
Warum verwenden Sie die SerializedNameAnnotation anstelle der Feldbenennungsstrategie Vasily?
Peterchaula
2
@Peter, da @SerializedNameich benutzerdefinierte Namen der Variablen verwenden kann, die möglicherweise nicht mit dem JSON-Schlüssel übereinstimmen. Und ja, Sie können nicht verwenden, @SerializedNamewenn Sie es nicht benötigen.
Vasily Bodnarchuk
2

Sie können ähnliche in der Kotlin-Klasse verwenden

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
}

Und auch für verschachtelte Klassen können Sie dasselbe verwenden, als ob es ein verschachteltes Objekt gibt. Geben Sie einfach den Serialize-Namen für die Klasse an.

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

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

}

Wenn Sie also eine Antwort vom Server erhalten, wird jeder Schlüssel JOSN zugeordnet.

Konvertieren Sie außerdem List in JSON:

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

ndroid konvertiert von JSON zu Object:

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