Ich habe eine JSON-Antwort, die wie folgt aussieht:Wie dynamisch benannte JSonarray mit Gson und Retrofit2 analysieren?
{
"equipment_layer": [
{
"id": 2,
"name": "Gateway",
"detail": "All gateways"
},
{
"id": 3,
"name": "Node",
"detail": "All Nodes"
},
{
"id": 1,
"name": "Miscellaneous",
"detail": "All miscellaneous assets"
},
{
"id": 4,
"name": "Sensors",
"detail": "All Sensors"
},
{
"id": 5,
"name": "IRM",
"detail": "Installation required material"
},
{
"id": 6,
"name": "Communication",
"detail": "All communication devices such as Cellular Router, ETU etc. which are purely communication"
}
],
"data": {
"1": [
{
"equipment_id": 353,
"item_quantity": 1,
"name": "DC Current Transformer (20mm) (Old)",
"shortcode": "SNS-DCI-CT20m-R1A",
"part_number": "718,804,805,",
"equipment_layer_id": 1,
"equipment_layer_name": "Miscellaneous"
},
{
"equipment_id": 357,
"item_quantity": 1,
"name": "Fuel Sensor - B4 (Old)",
"shortcode": "SNS-FUL-PSR-R1A",
"part_number": "718,810,811",
"equipment_layer_id": 1,
"equipment_layer_name": "Miscellaneous"
}
],
"2": [
{
"equipment_id": 345,
"item_quantity": 1,
"name": "RTU (Old)",
"shortcode": "RAN-RTU-PMCL-R1A",
"part_number": "787,788,789",
"equipment_layer_id": 2,
"equipment_layer_name": "Gateway"
}
],
"3": [
{
"equipment_id": 356,
"item_quantity": 1,
"name": "Battery Analyzer (Product) (Old)",
"shortcode": "RAN-BAM-PMCL-R1A",
"part_number": "787,808,809",
"equipment_layer_id": 3,
"equipment_layer_name": "Node"
}
],
"4": [
{
"equipment_id": 346,
"item_quantity": 1,
"name": "DC Current Transformer (30mm) (Old)",
"shortcode": "SNS-CT-DCI-R1A",
"part_number": "718,792,793",
"equipment_layer_id": 4,
"equipment_layer_name": "Sensors"
},
{
"equipment_id": 350,
"item_quantity": 1,
"name": "AC Block CT (Old)",
"shortcode": "SNS-ACI-BLK-R1A",
"part_number": "718,790,791",
"equipment_layer_id": 4,
"equipment_layer_name": "Sensors"
}
]
}
}
nun der Teil nach den „Daten“ Label ist dynamisch, in einer Reaktion, die ich Sub-Arrays von „1“, „2“, aber nicht von haben kann "3" oder "4". Das POJO der Daten im Inneren ist das gleiche wie Sie sehen können. Wie kann ich diese Daten analysieren? Ich benutze Rerofit2 mit Gson.converterfactory. Ich habe jsonchema2pojo auch versucht, aber die Daten innerhalb des "Daten" Gegenstandes werden nicht angezeigt.
Ich habe versucht, diese Methode zu folgen: Parsing Retrofit2 result using Gson with different JSON structures, aber ich kann nicht scheinen, den UnrwapConverter auszulösen. Dies ist meine converterfactory Umsetzung:
internal class UnwrappingGsonConverterFactory private constructor(private val gson: Gson) : Converter.Factory() {
override fun responseBodyConverter(type: Type, annotations: Array<Annotation>, retrofit: Retrofit): Converter<ResponseBody, *> ?{
if (!needsUnwrapping(annotations)) {
return super.responseBodyConverter(type, annotations, retrofit)
}
val typeAdapter = gson.getAdapter(TypeToken.get(type))
return UnwrappingResponseConverter(typeAdapter)
}
private class UnwrappingResponseConverter (private val typeAdapter: TypeAdapter<*>) : Converter<ResponseBody, Any> , AnkoLogger{
@Throws(IOException::class)
override fun convert(responseBody: ResponseBody): Any? {
responseBody.use { responseBody ->
JsonReader(responseBody.charStream()).use({ jsonReader ->
// Checking if the JSON document current value is null
val token = jsonReader.peek()
if (token === JsonToken.NULL) {
return null
}
// If it's an object, expect `{`
jsonReader.beginObject()
var value: Any? = null
// And iterate over all properties
while (jsonReader.hasNext()) {
val data = jsonReader.nextName()
debug("Unwrap Stuff: $data")
when (data) {
"1", "2", "3", "4", "5", "6" -> value = typeAdapter.read(jsonReader)
else ->jsonReader.skipValue()
}
}
// Consume the object end `}`
jsonReader.endObject()
return value
})
}
}
}
companion object {
fun create(gson: Gson): Converter.Factory {
return UnwrappingGsonConverterFactory(gson)
}
private fun needsUnwrapping(annotations: Array<Annotation>): Boolean {
for (annotation in annotations) {
if (annotation is Unwrap) {
return true
}
}
return false
}
}
}
Und die Schnittstelle:
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION)
annotation class Unwrap
Meine Datenklassen sind diese:
data class ActivityNodes(@SerializedName("equipment_layer") val equipmentLayer: List<EquipmentLayer>,
@SerializedName("data") val data: nodeData)
data class nodeData (@SerializedName("1") val nodeList: List<dataItem>) <-- this is where I need someway to tell SerializedName that the value can be anything from 1 to 6
data class dataItem(@SerializedName("equipment_id") val equipmentId: Int,
@SerializedName("item_quantity") val itemQuantity: Int,
@SerializedName("name") val name: String,
@SerializedName("shortcode") val shortCode: String,
@SerializedName("part_number") val partNumber: String,
@SerializedName("equipment_layer_id") val equipmentLayerId: Int,
@SerializedName("equipment_layer_name") val equipmentLayerName: String,
var isScanned: Boolean = false)
data class EquipmentLayer(@SerializedName("id") val id: Int,
@SerializedName("name") val name: String,
@SerializedName("detail") val details: String)
helfen Sie, den Code setzen sollten, die Sie – joao86