Класс данных Kotlin от Json с использованием GSON

105

У меня есть класс Java POJO:

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

и у меня есть класс данных Kotlin.

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

Как предоставить аннотацию в переменные Java json keyдля любых переменных, kotlin data classподобных @SerializedNameаннотации?

Erluxman
источник
1
Как у вас это получилось на Java? Покажи пример.
nhaarman
Что такое селектор json?
Воддан
@voddan то, что я имел в виду под этим селектором json, - это строки, которые я могу использовать для выбора конкретного объекта / массива json: в моем случае «тема», «идентификатор», «изображение». Надеюсь, я вам ясно дал понять. Спасибо :)
erluxman
@nhaarman Я отредактировал вопрос, надеюсь, это то, что вы имеете в виду,
erluxman

Ответы:

228

Класс данных:

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)
Антон Головин
источник
37
Используйте аннотации только в случае несоответствия имени переменной. Иначе да, не нужно
Вик
3
На мой взгляд, аннотации позволяют нам иметь классы, которые при сериализации могут быть исключены или включать переменные. Очень полезно при использовании дооснащения. Это не отправляет мусор на сервер. Кроме того, когда есть изменения в именах переменных на стороне сервера, более болезненно изменять их непосредственно в переменной класса, чем в аннотации.
Денеб Чорный
11
@Vik следует отметить, что имена ваших переменных могут быть обфусцированы (как в приложении для Android), но аннотация останется нетронутой
Caleb_Allen
@AntonGolovin Я не могу передать свой класс данных из метода Json. Нужно ли мне объявлять свой класс данных внутри файла java?
Рави Ядав
Если вы сделаете это, я считаю, что вы потеряете формат JSON, что может привести к IllegalStateException в будущем,
портфолио,
19

По ответу Антона Головина

подробности

  • Версия Gson: 2.8.5
  • Android Studio 3.1.4
  • Версия Kotlin: 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аннотацию вместо стратегии именования полей, Василий?
peterchaula
2
@Peter, потому @SerializedNameчто позволит мне использовать собственные имена переменных, которые могут не совпадать с ключом json. И да, вы можете не использовать, @SerializedNameесли вам это не нужно.
Василий Боднарчук
2

Вы можете использовать аналогичный в классе 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
}

А также для вложенного класса вы можете использовать то же самое, что и вложенный объект. Просто укажите имя Serialize для класса.

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

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

}

поэтому, если получен ответ от сервера, каждый ключ будет отображаться с JOSN.

Алос, конвертируйте List в JSON:

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

ndroid конвертировать из JSON в Object:

val json = getJson()
val topic = gson.fromJson(json, Topic::class.java)
Паван Сони
источник