在 moshi 中序列化时如何忽略字段?
How to ignore field when Serializing in moshi?
我是 Moshi 和 Kotlin 的新手,我实际上制作了两种方法,它们 returns 来自我的 Room 数据库的数据,并仅从两个对象制作一个,然后我将通过 Moshi 序列化。
有没有办法从序列化中忽略或删除某些字段?我尝试使用 @Transient 但由于我的模型结构引发了很多错误。
这是我的模型的样子:
@JsonClass(generateAdapter = true)
@Entity(tableName = "corpo", foreignKeys = [
ForeignKey(
entity = Testata::class,
parentColumns = ["id"],
childColumns = ["id_testata"],
onDelete = CASCADE
)
], indices = [ Index("id_testata") ], primaryKeys = [
"barcode", "id_testata"
])
data class Corpo(
var barcode: String,
var desc: String?, // ignore this
@ColumnInfo(defaultValue = "PZ")
var um: String, // ignore this
var qta: Float,
var id_testata: Int // i have to ignore this
)
和
@JsonClass(generateAdapter = true)
@Entity(tableName = "testata")
data class Testata(
@PrimaryKey(autoGenerate = true)
var id: Int,
var cod: String,
var tipo: String,
var cod_fornitore: String,
var desc_fornitore: String, // ignore this
var data: String,
var inviato: Boolean // ignore this
){
constructor(cod: String, tipo: String, cod_fornitore: String, desc_fornitore: String, data: String, inviato: Boolean)
: this(0, cod, tipo, cod_fornitore, desc_fornitore, data, inviato)
}
@JsonClass(generateAdapter = true) // this is my class which combine the two classes from Room db
data class Documento(
var testata: Testata,
var corpo: List<Corpo>
)
在这里我通过 Moshi 获得了我的序列化对象:
val moshi = Moshi.Builder().build()
val jsonAdapter: JsonAdapter<Documento> = moshi.adapter(Documento::class.java)
val documento = Documento(corpoViewModel.selectTestata(testata.id), corpoViewModel.selectCorpo(testata.id))
val json = jsonAdapter.toJson(documento)
此时我如何忽略我评论的字段并将它们从我的序列化中删除?
我看到 2 个适合您的用例的可行选项。
在您开始之前,您需要 2 个单独的 classes 用于所需的序列化 json,您可以选择:
使用映射器将一个 dto 映射到另一个。
使用 Moshi 的 Custom Type Adapter 来处理 Testata
和 Corpo
的映射
首先,定义两个想要的模型:
data class JsonCorpo(
var barcode: String,
var qta: Float,
)
data class JsonTestata(
var id: Int,
var cod: String,
var tipo: String,
var cod_fornitore: String,
var data: String,
)
并在组合 Documento
class
中使用 JsonTestata
和 JsonCorpo
而不是 Testata
和 Corpo
选项 1
我通常有一个映射器界面。
如果你使用像 Dagger 这样的注入框架,这会很方便,因为你不必记住映射器的名称 class.
/**
* Base mapper to convert [Input] type to [Output] type.
*/
interface Mapper<Input, Output> {
/**
* Transforms [input] into [Output].
*
* @param input the input to be transformed
* @return transformation result [Output]
*/
fun map(input: Input): Output
/**
* Transforms a [List] of [Input] into a [List] of [Output].
*
* @param input The input to be transformed
* @return transformation result
*/
fun map(input: List<Input>): List<Output> {
val result: MutableList<Output> = LinkedList()
for (item in input) {
result.add(map(item))
}
return result
}
}
并声明每个映射:
class CorpoToJsonCorpoMapper: Mapper<Corpo, SerializedCorpo> {
override fun map(input: Corpo): SerializedCorpo = with(input) {
SerializedCorpo(barcode, qta)
}
}
class TestataToJsonTestataMapper: Mapper<Testata, SerializedTestata> {
override fun map(input: Testata): SerializedTestata = with(input) {
SerializedTestata(id, cod, tipo, cod_fornitore, data)
}
}
然后你可以使用两个映射器来映射来自
的结果
corpoViewModel.selectTestata(testata.id)
和
corpoViewModel.selectCorpo(testata.id)
选项 2
您让 Moshi 的适配器负责映射:
class CorpoJsonAdapter {
@FromJson Event corpoFromJson(JsonCorpo jsonCorpo) {
return Corpo(
...
// Here handle the deserialization
);
}
@ToJson JsonCorpo corpoToJson(Corpo corpo) {
return JsonCorpo(corpo.barcode, corpo.qta)
}
}
和类似声明 TestataJsonAdapter
来处理 Testata
class.
的序列化和反序列化
我是 Moshi 和 Kotlin 的新手,我实际上制作了两种方法,它们 returns 来自我的 Room 数据库的数据,并仅从两个对象制作一个,然后我将通过 Moshi 序列化。
有没有办法从序列化中忽略或删除某些字段?我尝试使用 @Transient 但由于我的模型结构引发了很多错误。
这是我的模型的样子:
@JsonClass(generateAdapter = true)
@Entity(tableName = "corpo", foreignKeys = [
ForeignKey(
entity = Testata::class,
parentColumns = ["id"],
childColumns = ["id_testata"],
onDelete = CASCADE
)
], indices = [ Index("id_testata") ], primaryKeys = [
"barcode", "id_testata"
])
data class Corpo(
var barcode: String,
var desc: String?, // ignore this
@ColumnInfo(defaultValue = "PZ")
var um: String, // ignore this
var qta: Float,
var id_testata: Int // i have to ignore this
)
和
@JsonClass(generateAdapter = true)
@Entity(tableName = "testata")
data class Testata(
@PrimaryKey(autoGenerate = true)
var id: Int,
var cod: String,
var tipo: String,
var cod_fornitore: String,
var desc_fornitore: String, // ignore this
var data: String,
var inviato: Boolean // ignore this
){
constructor(cod: String, tipo: String, cod_fornitore: String, desc_fornitore: String, data: String, inviato: Boolean)
: this(0, cod, tipo, cod_fornitore, desc_fornitore, data, inviato)
}
@JsonClass(generateAdapter = true) // this is my class which combine the two classes from Room db
data class Documento(
var testata: Testata,
var corpo: List<Corpo>
)
在这里我通过 Moshi 获得了我的序列化对象:
val moshi = Moshi.Builder().build()
val jsonAdapter: JsonAdapter<Documento> = moshi.adapter(Documento::class.java)
val documento = Documento(corpoViewModel.selectTestata(testata.id), corpoViewModel.selectCorpo(testata.id))
val json = jsonAdapter.toJson(documento)
此时我如何忽略我评论的字段并将它们从我的序列化中删除?
我看到 2 个适合您的用例的可行选项。
在您开始之前,您需要 2 个单独的 classes 用于所需的序列化 json,您可以选择:
使用映射器将一个 dto 映射到另一个。
使用 Moshi 的 Custom Type Adapter 来处理
的映射Testata
和Corpo
首先,定义两个想要的模型:
data class JsonCorpo(
var barcode: String,
var qta: Float,
)
data class JsonTestata(
var id: Int,
var cod: String,
var tipo: String,
var cod_fornitore: String,
var data: String,
)
并在组合 Documento
class
JsonTestata
和 JsonCorpo
而不是 Testata
和 Corpo
选项 1
我通常有一个映射器界面。 如果你使用像 Dagger 这样的注入框架,这会很方便,因为你不必记住映射器的名称 class.
/**
* Base mapper to convert [Input] type to [Output] type.
*/
interface Mapper<Input, Output> {
/**
* Transforms [input] into [Output].
*
* @param input the input to be transformed
* @return transformation result [Output]
*/
fun map(input: Input): Output
/**
* Transforms a [List] of [Input] into a [List] of [Output].
*
* @param input The input to be transformed
* @return transformation result
*/
fun map(input: List<Input>): List<Output> {
val result: MutableList<Output> = LinkedList()
for (item in input) {
result.add(map(item))
}
return result
}
}
并声明每个映射:
class CorpoToJsonCorpoMapper: Mapper<Corpo, SerializedCorpo> {
override fun map(input: Corpo): SerializedCorpo = with(input) {
SerializedCorpo(barcode, qta)
}
}
class TestataToJsonTestataMapper: Mapper<Testata, SerializedTestata> {
override fun map(input: Testata): SerializedTestata = with(input) {
SerializedTestata(id, cod, tipo, cod_fornitore, data)
}
}
然后你可以使用两个映射器来映射来自
的结果corpoViewModel.selectTestata(testata.id)
和
corpoViewModel.selectCorpo(testata.id)
选项 2
您让 Moshi 的适配器负责映射:
class CorpoJsonAdapter {
@FromJson Event corpoFromJson(JsonCorpo jsonCorpo) {
return Corpo(
...
// Here handle the deserialization
);
}
@ToJson JsonCorpo corpoToJson(Corpo corpo) {
return JsonCorpo(corpo.barcode, corpo.qta)
}
}
和类似声明 TestataJsonAdapter
来处理 Testata
class.