You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Kotlin项目Moshi解析报错Expected BEGIN_ARRAY but was STRING求解

问题根因

这个报错的核心原因是PalletsPicked同步时服务端返回的响应内容不是你预期的纯JSON数组,两种报错的对应逻辑:

  • 最初的JsonEncodingException是因为响应里掺杂了JSON之外的多余内容,导致Moshi识别为非法JSON格式
  • 开启lenient后Moshi放宽了解析规则,把整个带多余内容的响应当成了字符串处理,所以抛出Expected BEGIN_ARRAY but was STRING的类型不匹配错误

Devices同步正常说明你的Moshi、Retrofit配置本身没有问题,问题集中在PalletsPicked对应的服务端处理逻辑、或者上传的PalletsPicked数据触发了服务端异常输出。

排查解决步骤
  1. 优先打印原始响应确认内容
    临时修改Retrofit接口定义,先不做自动JSON解析,直接拿到原始响应体打印内容,确认实际返回的是什么:
// 临时修改接口用于调试
@FormUrlEncoded
@POST("sync_up.php")
suspend fun syncUp(@Field("table") Table: String,
                     @Field("deviceid") DeviceID: Int,
                     @Field("key") DeviceKey: String,
                     @Field("data") Data: String): ResponseBody
// 调用处打印完整响应
val rawResponse = SyncUpApi.retrofitService.syncUp("pallets_picked", _deviceid, _deviceKey, palletsPickedJson)
Log.d("RAW_RESPONSE", "响应内容:${rawResponse.string()}")

如果打印出来的内容除了预期的JSON数组之外还有PHP报错信息、调试输出、多余的空格/换行/BOM头,直接定位对应输出的位置删除即可。

  1. 检查服务端PalletsPicked处理逻辑
  • 确认该逻辑块内没有遗留的echo、var_dump、print_r等调试输出代码
  • 检查PHP文件开头<?php前有没有空格、换行,文件末尾如果有?>标记建议直接删除,避免末尾多余字符被输出
  • 关闭PHP错误输出或者把错误写入日志不要输出到响应体,避免触发异常时错误信息破坏JSON格式
  • 输出JSON前统一加Content-Type声明:
<?php
// 所有逻辑处理完成后,输出前加头声明
header('Content-Type: application/json; charset=utf-8');
echo json_encode($response);
  1. 验证上传数据合法性
    检查你传入的palletsPickedJson是否有未转义的特殊字符、语法错误,避免服务端解析上传数据时触发异常,返回错误信息而非预期的JSON响应。

内容的提问来源于stack exchange,提问作者sonfollower

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 19:36:04