Reputation: 4307
Im new to Moshi and Kotlin and i actually made two methods which returns data from my Room database and make from two objects only one which then i'm going to serialize via Moshi.
Is there a way to ignore or remove some fields from serialization? i tried by using @Transient but that throw lot of errors cause of my model structure.
Here is how my models looks like:
@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
)
And
@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>
)
And here i get my serialized object via 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)
At this point how can i ignore the fields i commented and remove them from my serialization?
Upvotes: 1
Views: 1478
Reputation: 472
I see 2 viable options for your use case.
Before you go you will need 2 separate classes for the desired serialized json and you can choose:
Using a Mapper to map one dto to the other.
Using a Moshi's Custom Type Adapter for handling the mapping of both Testata
and Corpo
First of all, define the two desired models:
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,
)
And use JsonTestata
and JsonCorpo
instead of Testata
and Corpo
, inside your combined Documento
class
Option 1
I usually have an interface for mappers. This is handy if you use an injection framework like Dagger because you don't have to remember the name of the mapper 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
}
}
And declare each mapping:
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)
}
}
And then you can use the two mappers to map the result from
corpoViewModel.selectTestata(testata.id)
and
corpoViewModel.selectCorpo(testata.id)
Option 2
You let a Moshi's adapter take care of the mapping:
class CorpoJsonAdapter {
@FromJson Event corpoFromJson(JsonCorpo jsonCorpo) {
return Corpo(
...
// Here handle the deserialization
);
}
@ToJson JsonCorpo corpoToJson(Corpo corpo) {
return JsonCorpo(corpo.barcode, corpo.qta)
}
}
and similar declaring a TestataJsonAdapter
to handle the serialization and deserialization for the Testata
class.
Upvotes: 2