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

Retrofit动态JSON响应类型变更适配问题求助

解决Retrofit中动态JSON字段(int/String兼容)的适配问题

这个问题我之前也碰到过,确实挺头疼的——Gson默认的类型匹配太严格,遇到这种同一字段时而返回int、时而返回String的JSON响应,直接就会抛出类型转换异常。不过不用改Rest Adapter,咱们在现有ApiClient架构的基础上,通过自定义Gson的类型适配器就能完美解决,给你两种可行的方案:

方案一:全局适配所有int/Integer字段

这种方案适合你希望所有涉及int类型的Model字段都能自动兼容String类型的场景,只需要修改ApiClient中的Gson配置即可:

1. 自定义类型适配器

先写一个TypeAdapter,用来处理int和String之间的自动转换:

import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;

public class IntStringTypeAdapter extends TypeAdapter<Integer> {
    @Override
    public void write(JsonWriter out, Integer value) throws IOException {
        // 写数据时直接输出int值即可
        out.value(value);
    }

    @Override
    public Integer read(JsonReader in) throws IOException {
        // 读取数据时判断当前字段的类型
        if (in.peek() == JsonToken.STRING) {
            // 如果是String类型,尝试转成int
            String stringValue = in.nextString();
            try {
                return Integer.parseInt(stringValue);
            } catch (NumberFormatException e) {
                // 转换失败时可以返回默认值,或者根据业务需求抛异常
                return 0; // 这里的默认值你可以自己调整
            }
        } else if (in.peek() == JsonToken.NULL) {
            // 如果字段是null,返回null或者默认值
            in.nextNull();
            return null;
        } else {
            // 原本的int类型,直接读取
            return in.nextInt();
        }
    }
}

2. 修改ApiClient的Gson配置

把自定义的TypeAdapter注册到Gson实例中,替换原来默认的Gson:

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class ApiClient {
    public static final String BASE_URL = "http:***********";
    private static Retrofit retrofit = null;

    public static Retrofit getClient() {
        if (retrofit == null) {
            // 创建自定义Gson实例,注册我们的类型适配器
            Gson customGson = new GsonBuilder()
                    .registerTypeAdapter(Integer.class, new IntStringTypeAdapter())
                    .registerTypeAdapter(int.class, new IntStringTypeAdapter()) // 处理基本类型int
                    .create();

            retrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create(customGson)) // 使用自定义Gson
                    .build();
        }
        return retrofit;
    }
}

这样修改后,所有Model中的int/Integer字段都会自动兼容JSON中的String类型,不用逐个修改Model类。

方案二:针对单个Model字段适配

如果你只需要处理某几个特定的字段,不想全局生效,可以用@JsonAdapter注解直接在Model字段上指定适配器:

import com.google.gson.annotations.JsonAdapter;

public class YourModel {
    // 只给这个字段指定适配器
    @JsonAdapter(IntStringTypeAdapter.class)
    private int targetField;

    // 其他字段保持原来的类型
    private String otherField;

    // getter和setter方法
}

这种方式更灵活,不会影响其他无关字段的解析逻辑。

注意事项

  • 转换失败的处理:上面的适配器中我返回了默认值0,你可以根据业务需求改成抛出异常,或者返回其他默认值(比如-1表示无效)。
  • 空值处理:如果JSON字段可能为null,记得在适配器中处理JsonToken.NULL的情况,避免空指针异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:51:00