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

Retrofit无法获取响应报JsonSyntaxException,Logcat可见正常返回

解决Retrofit解析JSON时的JsonSyntaxException(NumberFormatException)问题

我来帮你拆解下这个问题:你看到的JsonSyntaxException本质是数值类型不匹配导致的——接口返回的collection_id值是57213780054,这个数已经远远超出了Java中int类型的最大取值(int最大值是2147483647),Gson在尝试把这个大数值转成int时直接抛出了NumberFormatException,这就是为什么你能通过HTTPLoggingInterceptor看到响应正常,但call.enque()始终进不了onSuccess()的原因。

最直接的解决方案:修改实体类字段类型

既然数值超出了int的范围,那我们把实体类中collection_id的类型改成long就可以了,long的取值范围足够容纳这个数值:

// 你的CollectionListing实体类
public class CollectionListing {
    // 将int替换为long
    private long collection_id;
    private String updated_at;
    private String body_html;
    private Object default_product_image;
    private String handle;
    private Image image;

    // 内部Image类保持不变
    public static class Image {
        private String created_at;
        private String src;
        
        // 记得添加getter、setter方法
    }

    // 为所有字段添加getter、setter
}

特殊场景:无法修改实体类时的替代方案

如果因为某些限制不能修改实体类,你可以自定义Gson的TypeAdapter来处理这个字段的转换(但不推荐,因为可能会丢失数据):

public class IntToLongAdapter extends TypeAdapter<Integer> {
    @Override
    public void write(JsonWriter out, Integer value) throws IOException {
        out.value(value);
    }

    @Override
    public Integer read(JsonReader in) throws IOException {
        if (in.peek() == JsonToken.NUMBER) {
            // 先把数值读成字符串,再尝试转成int
            String numStr = in.nextString();
            try {
                // 注意:如果数值超过int范围,这里会截断,数据会丢失
                return Integer.parseInt(numStr);
            } catch (NumberFormatException e) {
                // 可以根据业务需求返回默认值,或者抛出自定义异常
                return 0;
            }
        }
        throw new JsonSyntaxException("Expected int but was " + in.peek());
    }
}

然后在创建Retrofit实例时,把这个自定义Adapter注册到Gson中:

Gson customGson = new GsonBuilder()
        .registerTypeAdapter(Integer.class, new IntToLongAdapter())
        .create();

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(你的BaseUrl)
        .addConverterFactory(GsonConverterFactory.create(customGson))
        .addInterceptor(new HTTPLoggingInterceptor().setLevel(HTTPLoggingInterceptor.Level.BODY))
        .build();

总结

优先选择第一种方案,直接修改字段类型为long,这是最安全且不会丢失数据的做法。第二种方案只适合特殊场景,因为大数值转int必然会导致数据截断,可能引发业务问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:00:37