Lớp dữ liệu Kotlin từ Json sử dụng GSON


104

Tôi có lớp Java POJO như thế này:

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

và tôi có một lớp dữ liệu Kotlin Như thế này

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

Làm thế nào để cung cấp json keycho bất kỳ biến nào kotlin data classgiống như @SerializedNamechú thích trong các biến java?


1
Bạn đã làm điều đó như thế nào trong Java? Hiển thị một ví dụ.
nhaarman

Bộ chọn json là gì?
voddan

@voddan ý của tôi khi nói về những json selector đó là các chuỗi mà tôi có thể sử dụng để chọn đối tượng / mảng json cụ thể: trong trường hợp của tôi là "topic", "id", "image". Tôi hy vọng tôi đã nói rõ với bạn. Cảm ơn :)
erluxman

@nhaarman Tôi đã chỉnh sửa câu hỏi, tôi hy vọng đó là những gì bạn có nghĩa là
erluxman

Câu trả lời:


226

Lớp dữ liệu:

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

tới JSON:

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

từ JSON:

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

36
Chỉ sử dụng chú thích khi tên biến không khớp. Nếu không, vâng, không cần thiết
Vik

3
Theo ý kiến ​​của tôi, các chú thích cho phép chúng ta có các lớp mà khi tuần tự hóa có thể được loại trừ hoặc bao gồm các biến. Rất hữu ích khi sử dụng với trang bị thêm. Điều này không gửi rác đến máy chủ. Ngoài ra, khi có thay đổi về tên của các biến ở phía máy chủ, việc thay đổi nó trực tiếp trong biến lớp sẽ gây khó khăn hơn trong chú thích.
Deneb Chorny

10
@Vik một điều cần lưu ý là tên biến của bạn có thể có thể được obfuscated (như trong một ứng dụng Android) nhưng chú thích sẽ bị bỏ lại nguyên vẹn
Caleb_Allen

@AntonGolovin Tôi không thể chuyển lớp dữ liệu của mình vào từ phương thức Json. Tôi có cần khai báo lớp dữ liệu của mình bên trong tệp java không?
Ravi Yadav

Nếu bạn làm điều này, tôi tin rằng bạn sẽ bị mất định dạng JSON có thể gây IllegalStateException xuống đường
portfoliobuilder

19

Dựa trên câu trả lời của Anton Golovin

Chi tiết

  • Phiên bản Gson: 2.8.5
  • Android Studio 3.1.4
  • Phiên bản Kotlin: 1.2.60

Giải pháp

Tạo bất kỳ dữ liệu lớp nào và kế thừa giao diện JSONConvertable

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

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

Sử dụng

Lớp dữ liệu

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

Từ JSON

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

Tới JSON

val json = object.toJSON()

Tại sao bạn sử dụng SerializedNamechú thích thay vì chiến lược đặt tên trường, Vasily?
peterchaula

2
@Peter vì @SerializedNamesẽ cho phép tôi sử dụng tên tùy chỉnh của các biến có thể không khớp với khóa json. Và có, bạn có thể không sử dụng @SerializedNamenếu bạn không cần thiết.
Vasily Bodnarchuk

2

Bạn có thể sử dụng tương tự trong lớp 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
}

Và đối với lớp lồng nhau, bạn có thể sử dụng tương tự như nếu có đối tượng lồng nhau. Chỉ cần cung cấp tên Serialize cho Lớp.

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

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

}

vì vậy nếu nhận được phản hồi từ máy chủ, mỗi khóa sẽ ánh xạ với JOSN.

Alos, chuyển đổi Danh sách thành JSON:

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

ndroid chuyển đổi từ JSON thành Đối tượng:

val json = getJson()
val topic = gson.fromJson(json, Topic::class.java)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.