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

从Retrofit响应解析JSONArray失败,请求协助排查问题

解析Retrofit响应时JSONArray解析失败问题排查与修复

问题背景

我在解析Retrofit返回的JSON响应时遇到了JSONArray解析失败的问题,以下是相关信息:

服务器返回的JSON数据:

{ 
  "code": "200", 
  "contentType": "Json", 
  "data": [{ 
    "createdon": "2017-12-2", 
    "fname": "abhay", 
    "mobileno": "1234567890", 
    "userid": 1234, 
    "profileimagepath": null 
  }], 
  "maxjsonlength": 1233, 
  "message": "Success", 
  "status": true 
}

对应的Model类:

// 主Model类
public class Example {
    @SerializedName("code") @Expose private String code;
    @SerializedName("contentType") @Expose private String contentType;
    @SerializedName("data") @Expose private List<Datum> data = null;
    @SerializedName("maxjsonlength") @Expose private Integer maxjsonlength;
    @SerializedName("message") @Expose private String message;
    @SerializedName("status") @Expose private Boolean status;
    // getter和setter方法
}

// Data数组项的Model类
public class Datum {
    @SerializedName("createdon") @Expose private String createdon;
    @SerializedName("fname") @Expose private String fname;
    @SerializedName("mobileno") @Expose private String mobileno;
    @SerializedName("userid") @Expose private Integer userid;
    @SerializedName("profileimagepath") @Expose private Object profileimagepath;
    // getter和setter方法
}

Retrofit接口与调用代码:

// 接口定义
@Headers({ "Content-Type:application/json", "Bearer:mlm_token" })
@GET("api/v1.0/****/TestApi/{id}")
Call<Example> getTestJson(@Query("id") int userId);

// 调用代码
DrawerMethods msgInterface = (DrawerMethods) NetworkModule.getInstance().createClassInstance(DrawerMethods.class);
Call<Example> mLoginCall = msgInterface.getTestJson(userId);
mLoginCall.enqueue(new Callback<Example>() {
    @Override
    public void onResponse(Call<Example> call, Response<Example> response) {
        // 响应处理逻辑
    }
    @Override
    public void onFailure(Call<Example> call, Throwable t) {
        // 失败处理逻辑
    }
});

核心问题排查与修复

1. 路径参数与查询参数误用(最可能的原因)

你的Retrofit接口中,@GET路径里包含{id}路径参数,但你却用了@Query("id")来传递参数,这会导致请求的URL完全不符合服务器预期:

  • 错误的URL示例:api/v1.0/****/TestApi/{id}?id=123({id}会被原样保留,同时额外添加查询参数id=123)
  • 服务器期望的URL应该是:api/v1.0/****/TestApi/123

修复方法:将@Query("id")替换为@Path("id"),让Retrofit正确替换路径中的占位符:

@Headers({ "Content-Type:application/json", "Bearer:mlm_token" })
@GET("api/v1.0/****/TestApi/{id}")
Call<Example> getTestJson(@Path("id") int userId);

2. 其他可能的排查点

如果修复上述问题后仍无法解析,建议检查以下内容:

  • 确认Retrofit已配置Gson转换器:在构建Retrofit实例时,必须添加Gson转换器工厂,否则无法自动完成JSON到Model的映射:
    Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addConverterFactory(GsonConverterFactory.create()) // 这一行必须存在
        .build();
    
  • 检查服务器返回的实际响应:通过OkHttp的LoggingInterceptor打印完整的请求和响应内容,确认服务器返回的JSON结构与你预期的一致——比如是否存在data字段为非数组(单个对象或null)的特殊情况。
  • 兼容data字段的非数组场景:如果服务器在某些场景下返回data为单个对象或null,可以给Gson配置自定义TypeAdapter来兼容:
    Gson gson = new GsonBuilder()
        .registerTypeAdapter(new TypeToken<List<Datum>>(){}.getType(), new TypeAdapter<List<Datum>>() {
            @Override
            public void write(JsonWriter out, List<Datum> value) throws IOException {
                // 按需实现写入逻辑
            }
    
            @Override
            public List<Datum> read(JsonReader in) throws IOException {
                List<Datum> list = new ArrayList<>();
                if (in.peek() == JsonToken.BEGIN_OBJECT) {
                    // 单个对象转为列表
                    Datum datum = new Gson().fromJson(in, Datum.class);
                    list.add(datum);
                } else if (in.peek() == JsonToken.BEGIN_ARRAY) {
                    // 正常解析数组
                    in.beginArray();
                    while (in.hasNext()) {
                        Datum datum = new Gson().fromJson(in, Datum.class);
                        list.add(datum);
                    }
                    in.endArray();
                }
                return list;
            }
        })
        .create();
    
    然后在Retrofit构建时使用这个自定义Gson实例:
    .addConverterFactory(GsonConverterFactory.create(gson))
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:57:34