Клас даних Kotlin від Json за допомогою GSON


105

У мене клас Java POJO такий:

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

і у мене клас класів даних Котліна

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

Як надати json keyбудь-яким змінним kotlin data classподібну @SerializedNameанотацію у змінних Java?


1
Як ви це зробили на Java? Покажіть приклад.
nhaarman

Що таке селектор json?
воддан

@voddan, що я мав на увазі під цим селектором json, це ті рядки, які я можу використовувати для вибору конкретного об'єкта / масиву json: у моєму випадку "тема", "id", "зображення". Сподіваюся, я вам це зрозумів. Дякую :)
erluxman

@nhaarman Я відредагував це запитання, я сподіваюся, що саме так ви маєте на увазі
erluxman

Відповіді:


227

Клас даних:

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

до JSON:

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

від JSON:

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

36
Використовуйте примітки лише тоді, коли є невідповідність імені змінної. Інакше, так, не потрібно
Вік

3
На мою думку, анотації дозволяють нам мати класи, які при серіалізації можуть бути виключені або включати змінні. Дуже корисний при використанні з модернізацією. Це не надсилає сміття на сервер. Крім того, коли в імені змінних на стороні сервера є зміни, змінити його безпосередньо в змінній класу, ніж в анотації, болісніше.
Денеб Чорний

11
@Vik Одне зауваження - це те, що ваші імена змінних можуть бути затуманені (наприклад, у додатку для Android), але анотація залишиться недоторканою
Caleb_Allen

@AntonGolovin Я не в змозі передати свій клас даних з методу Json. Чи потрібно мені оголосити свій клас даних всередині файлу Java?
Раві Ядав

Якщо ви це зробите, я вважаю, що ви втратите формат JSON, що може спричинити IllegalStateException вниз по дорозі
portfoliobuilder

19

На основі відповіді Антона Головіна

Деталі

  • Версія Gson: 2.8.5
  • Android Studio 3.1.4
  • Версія Котліна: 1.2.60

Рішення

Створіть будь-які дані класу та успадкуйте інтерфейс JSONConvertable

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

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

Використання

Клас даних

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

Від JSON

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

До JSON

val json = object.toJSON()

Чому ви використовуєте SerializedNameпримітку замість стратегії іменування поля, Василю?
петершаула

2
@Peter тому @SerializedName, що дозволить мені використовувати власні імена змінних, які можуть не збігатися з ключем json. І так, ви можете не використовувати, @SerializedNameякщо вам це не потрібно.
Василь Боднарчук

2

Ви можете використовувати подібне в класі Котліна

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
}

А також для вкладеного класу ви можете використовувати те саме, як якщо є вкладений об'єкт. Просто введіть назву серіалізації для класу.

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

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

}

тому, якщо отримати відповідь від сервера, кожна клавіша буде зіставлятися з JOSN.

Alos, перетворити список у JSON:

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

Перетворення ndroid з JSON в Object:

val json = getJson()
val topic = gson.fromJson(json, Topic::class.java)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.