Kotlin项目中java.lang.IllegalStateException错误求助
问题:Retrofit解析报错
Expected BEGIN_ARRAY but was BEGIN_OBJECT 错误信息
java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
相关代码
ApiService 代码
@GET("/api/Demak/GetDemakBarcodeOlustur?") suspend fun getDemakBarcodes( @Query("api") api: String, @Query("islem") islem: String, @Query("malkod") malkod : String, @Query("birim") birim: String, @Query("barcodefield") barcodefield: String, @Query("barcodevalue") barcodevalue:String ): Response<List<DemakBarcodes>>
Model 代码
data class DemakBarcodes( val BARKOD1:String, val BARKOD2:String, val BARKOD3:String, val BARKOD4:String, val BARKOD5:String, )
页面逻辑代码
private fun updateBarcode(buttonName:String,editText:TextInputEditText,barcodeText:String){ viewModel.getDataDemakBarcodes(apiUrl,"DEGISTIR",malkod,birimKod,buttonName,barcodeText) viewModel.dataLoading.observeProgress(viewLifecycleOwner,binding.pgBar) viewModel.liveDataDemakBarcodes.myObserve( viewLifecycleOwner, success = { println("succesa girdi") if(buttonName=="BARCODE1"){ editText.setText(it[0].BARKOD1) } if(buttonName=="BARCODE2"){ editText.setText(it[0].BARKOD2) } if(buttonName=="BARCODE3"){ editText.setText(it[0].BARKOD3) } if(buttonName=="BARCODE4"){ editText.setText(it[0].BARKOD4) } if(buttonName=="BARCODE5"){ editText.setText(it[0].BARKOD5) } toastSuccess(str(R.string.barkod_guncellendi)) }, empty = { toastWarning("Boş Veri") }, error = { println("error : error") showErrorDialog( title = it, confirm={ }, buttonPositiveText = str(R.string.tamam), ) } ) }
ViewModel 代码
fun getDataDemakBarcodes(apiUrl: String,islem:String,malKod:String,birim:String,barcodefield:String,barcodevalue:String): SingleLiveEvent<NetworkResult<List<DemakBarcodes>>> { dataLoading.value = true viewModelScope.launch { api.getDemakBarcodes(apiUrl,islem,malKod,birim,barcodefield,barcodevalue) .getData(dataLoading) { liveDataDemakBarcodes.value = it } } return liveDataDemakBarcodes }
已尝试操作
- 为Model添加
@Serialized注解,问题未解决 - 确认SQL端存储过程运行正常
解决方案
这个错误的核心是接口返回的JSON格式与你定义的解析类型不匹配:你在ApiService中声明返回Response<List<DemakBarcodes>>,期望接口返回数组([]),但实际接口返回的是单个对象({}),或是包含数组的外层对象。
具体解决步骤:
确认接口实际返回的JSON结构
- 用Postman、Charles或Retrofit日志拦截器打印完整返回内容。常见两种情况:
- 情况1:返回包含数组的外层对象
{ "code": 200, "data": [{"BARKOD1":"xxx", "BARKOD2":"xxx", ...}] } - 情况2:直接返回单个
DemakBarcodes对象{"BARKOD1":"xxx", "BARKOD2":"xxx", ...}
- 情况1:返回包含数组的外层对象
- 用Postman、Charles或Retrofit日志拦截器打印完整返回内容。常见两种情况:
根据实际结构调整代码
针对情况1(外层包裹对象):
- 新增包裹类:
data class DemakBarcodeResponse( val data: List<DemakBarcodes> // 可添加其他字段如code、message等,按实际返回结构补充 ) - 修改ApiService返回类型:
suspend fun getDemakBarcodes(...): Response<DemakBarcodeResponse> - 页面逻辑调整为从包裹类中取数组:
success = { response -> val barcodeList = response.data if(barcodeList.isNotEmpty()){ if(buttonName=="BARCODE1"){ editText.setText(barcodeList[0].BARKOD1) } // 其他赋值逻辑同上 } }
- 新增包裹类:
针对情况2(单个对象):
- 修改ApiService返回类型:
suspend fun getDemakBarcodes(...): Response<DemakBarcodes> - 页面逻辑直接使用对象,无需数组索引:
success = { barcode -> if(buttonName=="BARCODE1"){ editText.setText(barcode.BARKOD1) } // 其他赋值逻辑同上 }
- 修改ApiService返回类型:
校验字段映射(可选)
- 若JSON返回的键名与Model字段名不一致,需用
@SerializedName明确映射,例如:@SerializedName("barkod1") val BARKOD1: String
- 若JSON返回的键名与Model字段名不一致,需用
内容的提问来源于stack exchange,提问作者Hasan Ozan
相关产品推荐
相关产品推荐

