如何定义变量可能不存在于数据 class (JSON/Kotlin) 中?
How to define that a variable may not be present in data class (JSON/Kotlin)?
我在 Kotlin 中有一个数据 class 和一个对象:
一个数据classTranche.kt
@JsonIgnoreProperties(ignoreUnknown = true)
data class Tranche(
@JsonProperty("id") var id: String,
@JsonProperty("status") var status: String,
@JsonProperty("instrumentType") var instrumentType: String,
@JsonProperty("ssdRepaymentDetails") var ssdRepaymentDetails: RepaymentDetails?,
@JsonProperty("loanRepaymentDetails") var loanRepaymentDetails: RepaymentDetails?
) : PayloadContent
还有一个 对象 在 DummyTransaction.kt
val trancheDummy = Tranche(id = "0", name = "dummy", status = "DRAFT", instrumentType = "Loan", ssdRepaymentDetails = repaymentDetailsDummy, loanRepaymentDetails = repaymentDetailsDummy)
将 RepaymentDetails 设置为可为 null 我允许 ssdDetails 和 loanDetails 为 null。这很好,但我不需要 ssdDetails 和 loanDetails。如果 instrumentType 是 SSD,我需要 ssdDetails;如果 instrumentType 是 Loan,我需要 loanDetails。
如果不保留不同产品的两个数据 class,我该怎么做?意思是,我想拥有以下两个对象:
val trancheDummySsd = Tranche(id = "0", name = "dummy", status = "DRAFT", instrumentType = "SSD", ssdRepaymentDetails = repaymentDetailsDummy)
val trancheDummyLoan = Tranche(id = "0", name = "dummy", status = "DRAFT", instrumentType = "Loan", loanRepaymentDetails = repaymentDetailsDummy)
需要的原因是 JSON 字符串对于 SSD 和贷款是不同的,而在后端读取它时,我只需要该字符串中的一个属性 (payCycle),并且该属性两种产品通用。
RepaymentDetails.kt
@JsonIgnoreProperties(ignoreUnknown = true)
data class RepaymentDetails(
@JsonProperty("payCycle") var payCycle: String?
)
这部分是用 Go 编写的,它定义了 JSON 结构:
type RepaymentDetails struct {
PayCycle string `json:"payCycle,omitempty"`
}
type LoanRepaymentDetails struct {
RepaymentDetails // inherits RepaymentDetails struct
}
type SsdRepaymentDetails struct {
RepaymentDetails // inherits RepaymentDetails struct
LastPaymentDate string `json:"lastPaymentDate,omitempty"`
}
在我看来,最好的做法是使用 sealed class
(为简洁起见删除了注释):
sealed class Tranche(var id: String, var status: String, var instrumentType: String) {
data class SSDTranche(id: String, status: String, var ssdDetails: RepaymentDetails) : Tranche(id, status, "SSD")
data class LoanTranche(id: String, status: String, var loanDetails: RepaymentDetails) : Tranche(id, status, "Loan")
}
但如果您真的不想使用两种不同的类型,您至少可以使用一个 init
块来验证您是否获得了正确的参数:
init {
when (instrumentType) {
"SSD" -> requireNotNull(ssdDetails)
"Loan" -> requireNotNull(loanDetails)
}
}
考虑到数据对象的 class 定义无论数据类型变量如何都不会改变,使用注释为 RepaymentDetails
类型的单个 "repaymentDetails"
Json 属性@JsonAlias("ssdRepaymentDetails", "loanRepaymentDetails")
足以将任一可能的有效负载反序列化为单个不可为 null 的字段。
正如 OP 强调的那样,可能需要额外的 @JsonProperty("repaymentDetails")
。
我在 Kotlin 中有一个数据 class 和一个对象:
一个数据classTranche.kt
@JsonIgnoreProperties(ignoreUnknown = true)
data class Tranche(
@JsonProperty("id") var id: String,
@JsonProperty("status") var status: String,
@JsonProperty("instrumentType") var instrumentType: String,
@JsonProperty("ssdRepaymentDetails") var ssdRepaymentDetails: RepaymentDetails?,
@JsonProperty("loanRepaymentDetails") var loanRepaymentDetails: RepaymentDetails?
) : PayloadContent
还有一个 对象 在 DummyTransaction.kt
val trancheDummy = Tranche(id = "0", name = "dummy", status = "DRAFT", instrumentType = "Loan", ssdRepaymentDetails = repaymentDetailsDummy, loanRepaymentDetails = repaymentDetailsDummy)
将 RepaymentDetails 设置为可为 null 我允许 ssdDetails 和 loanDetails 为 null。这很好,但我不需要 ssdDetails 和 loanDetails。如果 instrumentType 是 SSD,我需要 ssdDetails;如果 instrumentType 是 Loan,我需要 loanDetails。
如果不保留不同产品的两个数据 class,我该怎么做?意思是,我想拥有以下两个对象:
val trancheDummySsd = Tranche(id = "0", name = "dummy", status = "DRAFT", instrumentType = "SSD", ssdRepaymentDetails = repaymentDetailsDummy)
val trancheDummyLoan = Tranche(id = "0", name = "dummy", status = "DRAFT", instrumentType = "Loan", loanRepaymentDetails = repaymentDetailsDummy)
需要的原因是 JSON 字符串对于 SSD 和贷款是不同的,而在后端读取它时,我只需要该字符串中的一个属性 (payCycle),并且该属性两种产品通用。
RepaymentDetails.kt
@JsonIgnoreProperties(ignoreUnknown = true)
data class RepaymentDetails(
@JsonProperty("payCycle") var payCycle: String?
)
这部分是用 Go 编写的,它定义了 JSON 结构:
type RepaymentDetails struct {
PayCycle string `json:"payCycle,omitempty"`
}
type LoanRepaymentDetails struct {
RepaymentDetails // inherits RepaymentDetails struct
}
type SsdRepaymentDetails struct {
RepaymentDetails // inherits RepaymentDetails struct
LastPaymentDate string `json:"lastPaymentDate,omitempty"`
}
在我看来,最好的做法是使用 sealed class
(为简洁起见删除了注释):
sealed class Tranche(var id: String, var status: String, var instrumentType: String) {
data class SSDTranche(id: String, status: String, var ssdDetails: RepaymentDetails) : Tranche(id, status, "SSD")
data class LoanTranche(id: String, status: String, var loanDetails: RepaymentDetails) : Tranche(id, status, "Loan")
}
但如果您真的不想使用两种不同的类型,您至少可以使用一个 init
块来验证您是否获得了正确的参数:
init {
when (instrumentType) {
"SSD" -> requireNotNull(ssdDetails)
"Loan" -> requireNotNull(loanDetails)
}
}
考虑到数据对象的 class 定义无论数据类型变量如何都不会改变,使用注释为 RepaymentDetails
类型的单个 "repaymentDetails"
Json 属性@JsonAlias("ssdRepaymentDetails", "loanRepaymentDetails")
足以将任一可能的有效负载反序列化为单个不可为 null 的字段。
正如 OP 强调的那样,可能需要额外的 @JsonProperty("repaymentDetails")
。