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

如何在Retrofit中修改JSON响应体,直接获取List对象

直接解析外层含items的JSON为List(Retrofit+Gson)

不用再写UserRepresentation这类冗余的包装类,通过自定义Gson类型适配器就能实现让Retrofit直接返回List<User>这类结果,具体步骤如下:

1. 编写通用的TypeAdapterFactory

这个工厂类会自动识别List类型的解析请求,跳过外层的items包装,直接解析内部的数组元素:

public class ListResponseTypeAdapterFactory implements TypeAdapterFactory {
    @SuppressWarnings("unchecked")
    @Override
    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
        // 仅处理List类型
        if (!(type.getType() instanceof ParameterizedType) || 
            !List.class.isAssignableFrom((Class<?>) ((ParameterizedType) type.getType()).getRawType())) {
            return null;
        }
        
        // 获取List的泛型实体类型(比如List<User>里的User)
        Type elementType = ((ParameterizedType) type.getType()).getActualTypeArguments()[0];
        TypeAdapter<?> elementAdapter = gson.getAdapter(TypeToken.get(elementType));
        
        return (TypeAdapter<T>) new TypeAdapter<List<?>>() {
            @Override
            public void write(JsonWriter out, List<?> value) throws IOException {
                // 若请求需要包裹成items结构,可在此实现;仅处理响应的话可保留默认数组写法
                out.beginArray();
                for (Object item : value) {
                    elementAdapter.write(out, item);
                }
                out.endArray();
            }

            @Override
            public List<?> read(JsonReader in) throws IOException {
                in.beginObject();
                List<Object> resultList = new ArrayList<>();
                while (in.hasNext()) {
                    String fieldName = in.nextName();
                    if ("items".equals(fieldName)) {
                        // 解析items数组内的实体
                        in.beginArray();
                        while (in.hasNext()) {
                            resultList.add(elementAdapter.read(in));
                        }
                        in.endArray();
                    } else {
                        // 忽略响应中的其他无关字段
                        in.skipValue();
                    }
                }
                in.endObject();
                return resultList;
            }
        };
    }
}

2. 配置Gson并注入Retrofit

把自定义的适配器工厂注册到Gson实例中,再配置给Retrofit:

// 构建自定义Gson实例
Gson customGson = new GsonBuilder()
    .registerTypeAdapterFactory(new ListResponseTypeAdapterFactory())
    .create();

// 初始化Retrofit时使用这个自定义Gson
Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("你的API基础地址")
    .addConverterFactory(GsonConverterFactory.create(customGson))
    .build();

3. 修改Retrofit接口方法签名

现在可以直接在接口里用Call<List<实体类>>的形式,无需再定义包装类:

public interface ApiService {
    @GET("users")
    Call<List<User>> getUsers();

    @GET("repos")
    Call<List<Repo>> getRepos();
}

额外说明

  • 如果API返回的外层包裹字段不是items,只需修改适配器中"items"的字符串为对应字段名即可;
  • 若需要处理响应中的其他必填字段(比如总页数),可以在read方法中添加对应解析逻辑;
  • 若POST请求需要把列表包裹成{"items": [...]}的结构,完善write方法的逻辑即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 14:50:22