使用Retrofit如何处理API响应中类型不确定的status字段?
解决Retrofit中多类型JSON字段的解析问题
针对API返回的status字段可能为字符串、数组或null的情况,有两种实用的解决方式:
方式一:自定义Gson TypeAdapter
如果你的Retrofit使用Gson作为序列化工具,可以通过自定义TypeAdapter统一处理status的类型转换:
- 先调整ResponseModel,将
status定义为统一的List<String>类型(可根据业务需求改为String,这里以列表为例):
public class ResponseModel { private List<String> status; public List<String> getStatus() { return status; } public void setStatus(List<String> status) { this.status = status; } }
- 编写自定义TypeAdapter处理不同类型的解析:
public class StatusTypeAdapter extends TypeAdapter<List<String>> { @Override public void write(JsonWriter out, List<String> value) throws IOException { if (value == null) { out.nullValue(); return; } if (value.size() == 1) { out.value(value.get(0)); } else { out.beginArray(); for (String s : value) { out.value(s); } out.endArray(); } } @Override public List<String> read(JsonReader in) throws IOException { List<String> statusList = new ArrayList<>(); JsonToken token = in.peek(); switch (token) { case STRING: statusList.add(in.nextString()); break; case BEGIN_ARRAY: in.beginArray(); while (in.hasNext()) { statusList.add(in.nextString()); } in.endArray(); break; case NULL: in.nextNull(); return null; // 也可返回空列表,依业务需求调整 default: throw new JsonParseException("Unexpected token for status: " + token); } return statusList; } }
- 在Retrofit配置中注册该TypeAdapter:
Gson gson = new GsonBuilder() .registerTypeAdapter(new TypeToken<List<String>>() {}.getType(), new StatusTypeAdapter()) .create(); Retrofit retrofit = new Retrofit.Builder() .baseUrl("你的API基础地址") .addConverterFactory(GsonConverterFactory.create(gson)) .build();
方式二:用JsonElement接收并手动转换
如果不想自定义适配器,可直接用JsonElement接收status,在getter方法中做类型判断和转换:
import com.google.gson.JsonElement; import com.google.gson.JsonArray; public class ResponseModel { private JsonElement status; public List<String> getStatus() { List<String> statusList = new ArrayList<>(); if (status == null || status.isJsonNull()) { return statusList; } if (status.isJsonPrimitive() && status.getAsJsonPrimitive().isString()) { statusList.add(status.getAsString()); } else if (status.isJsonArray()) { JsonArray array = status.getAsJsonArray(); for (JsonElement element : array) { if (element.isJsonPrimitive() && element.getAsJsonPrimitive().isString()) { statusList.add(element.getAsString()); } } } return statusList; } }
这种方式无需额外配置Gson,直接在模型内处理类型兼容,适合简单场景。
注意事项
- 两种方式都可根据业务需求调整转换逻辑,比如把数组拼接成单个字符串返回,或仅取数组第一个元素。
- 若使用Moshi等其他序列化工具,思路类似,只需编写对应工具的自定义适配器即可。
内容的提问来源于stack exchange,提问作者Mohamed Aziz Laroussi
相关产品推荐
相关产品推荐

