Kotlin Data Class จาก Json โดยใช้ GSON


108

ฉันมีคลาส Java POJO ดังนี้:

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

และฉันมีคลาสข้อมูล Kotlin เช่นนี้

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

จะจัดเตรียมjson keyตัวแปรใด ๆ ที่kotlin data classคล้ายกับ@SerializedNameคำอธิบายประกอบในตัวแปร java ได้อย่างไร


1
คุณทำได้อย่างไรใน Java? แสดงตัวอย่าง
nhaarman

ตัวเลือก json คืออะไร?
voddan

@voddan สิ่งที่ฉันหมายถึงโดยตัวเลือก json เหล่านั้นคือสตริงที่ฉันสามารถใช้เพื่อเลือกวัตถุ / อาร์เรย์ json เฉพาะ: ในกรณีของฉันคือ "topic", "id", "image" ฉันหวังว่าฉันจะแจ้งให้คุณทราบอย่างชัดเจน ขอบคุณ :)
erluxman

@nhaarman ฉันแก้ไขคำถามแล้วฉันหวังว่านั่นคือสิ่งที่คุณหมายถึง
erluxman

คำตอบ:


235

ชั้นข้อมูล:

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)

38
ใช้คำอธิบายประกอบเฉพาะเมื่อชื่อตัวแปรไม่ตรงกัน มิฉะนั้นใช่ไม่จำเป็น
Vik

3
ในความคิดของฉันคำอธิบายประกอบช่วยให้เรามีคลาสที่เมื่อทำให้เป็นอนุกรมสามารถแยกออกหรือรวมตัวแปรได้ มีประโยชน์มากเมื่อใช้ร่วมกับชุดติดตั้งเพิ่มเติม สิ่งนี้ไม่ส่งขยะไปยังเซิร์ฟเวอร์ นอกจากนี้เมื่อมีการเปลี่ยนแปลงในชื่อของตัวแปรทางฝั่งเซิร์ฟเวอร์การเปลี่ยนชื่อในตัวแปรคลาสโดยตรงจะเจ็บปวดกว่าในคำอธิบายประกอบ
Deneb Chorny

12
@Vik สิ่งหนึ่งที่ควรทราบคือชื่อตัวแปรของคุณอาจทำให้สับสนได้ (เช่นในแอป Android) แต่คำอธิบายประกอบจะไม่เสียหาย
Caleb_Allen

@AntonGolovin ฉันไม่สามารถส่งผ่านคลาสข้อมูลของฉันจากเมธอด Json ได้ฉันจำเป็นต้องประกาศคลาสข้อมูลของฉันในไฟล์ java หรือไม่
Ravi Yadav

หากคุณทำเช่นนี้ฉันเชื่อว่าคุณจะสูญเสียรูปแบบ JSON ซึ่งอาจทำให้ IllegalStateException ลงระหว่างทาง
portfoliobuilder

19

จากคำตอบของAnton Golovin

รายละเอียด

  • เวอร์ชัน Gson: 2.8.5
  • Android Studio 3.1.4
  • Kotlin เวอร์ชัน: 1.2.60.2

วิธีการแก้

สร้างข้อมูลคลาสและสืบทอดอินเทอร์เฟซ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คำอธิบายประกอบแทนกลยุทธ์การตั้งชื่อฟิลด์ Vasily
peterchaula

2
@Peter เพราะ@SerializedNameจะช่วยให้ฉันใช้ชื่อที่กำหนดเองของตัวแปรซึ่งอาจไม่ตรงกับคีย์ json และใช่คุณไม่สามารถใช้@SerializedNameถ้าคุณไม่จำเป็นต้องใช้
Vasily Bodnarchuk

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

Alos แปลงรายการเป็น JSON:

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

ndroid แปลงจาก JSON เป็น Object:

val json = getJson()
val topic = gson.fromJson(json, Topic::class.java)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.