试图显示设计不佳的JSON并遇到问题。出于我的目的,不需要数组内的数组,因此我试图将其从响应中排除,以希望它不再引发错误。
丑陋的JSON
{
"id": "65",
"name": "Switch - Kitchen",
"label": "Switch - Kitchen",
"attributes": [
{
"name": "switch",
"currentValue": "off",
"dataType": "ENUM",
"values": [
"on",
"off"
]
}
],
"capabilities": [
"Switch",
{
"attributes": [
{
"name": "switch",
"dataType": null
}
]
},
"Configuration",
"Refresh",
"Actuator"
],
"commands": [
"configure",
"flash",
"off",
"on",
"refresh",
"refresh"
]
}
DeviceDetails类
@Transient val attributes: List<Attribute>,
val capabilities: List<String>,
val commands: List<String>,
val id: String,
val label: String,
val name: String
)
属性类(不需要)
data class Attribute(
val currentValue: String,
val dataType: String,
val name: String,
val values: List<String>
)
Details API
interface DeviceDetailsAPI {
@GET("devices/65")
fun getAllDetails(@Query("access_token") access_token: String): Observable<List<DeviceDetails>>
}
API调用
object DeviceDetailsWebAccess {
val deviceDetailsApi: DeviceDetailsAPIClient by lazy {
Log.d("DeviceDetailsWebAccess", "Creating details retrofit client")
//Debugging URL//
val interceptor : HttpLoggingInterceptor = HttpLoggingInterceptor().apply {
this.level = HttpLoggingInterceptor.Level.BODY }
val client : OkHttpClient = OkHttpClient.Builder().apply {
this.addInterceptor(interceptor)}.build()
//Debugging URL//
val retrofit = Retrofit.Builder()
.baseUrl("http://xxx.xxx.xxx.xxx/apps/api/109/")
// Moshi maps JSON to classes
.addConverterFactory(MoshiConverterFactory.create())
// The call adapter handles threads
.addCallAdapterFactory(CoroutineCallAdapterFactory())
.client(client)
.build()
// Create Retrofit client
return@lazy retrofit.create(DeviceDetailsAPIClient::class.java)
}
}
适配器
class DeviceDetailsAdapter (var deviceDetails: List<DeviceDetails>, val clickListener: (DeviceDetails) -> Unit) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val inflater = LayoutInflater.from(parent.context)
val view = inflater.inflate(R.layout.device_detail, parent, false)
return PartViewHolder(view)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
}
override fun getItemCount() = deviceDetails.size
class PartViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bind(device: DeviceList) {
itemView.device_item_name.text = device.name
itemView.device_item_id.text = device.id
itemView.device_item_label.text = device.label
}
}
}
主要活动
class MainActivity2 : AppCompatActivity() {
private val tag : String = MainActivity2::class.java.simpleName
private lateinit var adapterDetails: DeviceDetailsAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
rv_devices.layoutManager = LinearLayoutManager(this)
rv_devices.hasFixedSize()
adapterDetails = DeviceDetailsAdapter(listOf()) { deviceDetails: DeviceDetails -> deviceDetails }
rv_devices.adapter = adapterDetails
loadDeviceDetails()
}
private fun loadDeviceDetails() {
GlobalScope.launch(Dispatchers.Main) {
try {
val webResponseDetails = DeviceDetailsWebAccess.deviceDetailsApi.getDevicesDetailsAsync(access_token = "xxxxxxxx").await()
if (webResponseDetails.isSuccessful) {
val deviceDetails: List<DeviceDetails>? = webResponseDetails.body()
//Log.d(tag, deviceDetails?.toString())
//adapterDetails.deviceDetails = deviceDetails ?: listOf()
adapterDetails.notifyDataSetChanged()
} else {
Log.e(tag, "Error ${webResponseDetails.code()}")
Toast.makeText(this@MainActivity2, "Error ${webResponseDetails.code()}", Toast.LENGTH_LONG).show()
}
} catch (e: IOException) {
Log.e(tag, "Exception " + e.printStackTrace())
Toast.makeText(this@MainActivity2, "Exception ${e.message}", Toast.LENGTH_LONG).show()
}
}
}
}
我遇到以下错误:
com.squareup.moshi.JsonDataException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at path $
这并不指向我觉得奇怪的问题在哪里?我正在跟踪JSON调用,它显示“属性”数组仍在解析中。我究竟做错了什么?为什么瞬态不起作用?任何帮助表示赞赏。
答案 0 :(得分:2)
该错误表明该问题存在于作为根源的path $
上。
您的问题是您说的是JSON是List<DeviceDetails>
,但实际上它实际上只是一个DeviceDetails
。
答案 1 :(得分:0)
正如@Kiskae回答的那样,该类需要一个DeviceDetails列表,而当前的JSON将是一个DeviceDetails对象。
通常,模型类中的列表与[ {object 1}, {object 2} ]
的JSON中的数组语法相对应
您的根JSON是一个对象-要对其进行更改,以便您可以解析JSON,您需要在JSON中返回一个数组,这将意味着在对象1上方返回DeviceDetails,该对象上方映射到您的Observable<List<DeviceDetails>>
或更改获取详细信息api调用,以便它解析DeviceDetails对象Observable<DeviceDetails>
您发布的JSON意味着更改API以期望Observable<DeviceDetails>
解决此问题后,您将需要在DeviceDetails类中为Capabilities
对象建模,因为JSON不是String数组。它是未建模对象的数组。 (字符串,属性包装程序,字符串,字符串)