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

能否使用JSONObject替代JsonObject实现Retrofit读取JSON数据?

能否用JSONObject替代JsonObject实现Retrofit的JSON数据读取?

你当前用的是Gson库的com.google.gson.JsonObject来接收Retrofit的响应,但如果想换成Android原生的org.json.JSONObject,直接替换返回类型是行不通的——因为你配置的GsonConverterFactory只能处理Gson库相关的类型,没法自动把响应转换成Android原生的JSONObject。不过有两种可行的方案可以实现需求:

方案一:通过ResponseBody手动解析成JSONObject

这是最直接的方式,不需要额外自定义转换器,步骤如下:

  1. 修改你的Retrofit接口定义,把返回类型改为Call<ResponseBody>:
@POST("testservice")
@FormUrlEncoded
Call<ResponseBody> getRegisterUserData(
    @Header("x-dsn") String dsn,
    @Field("id") String id
);
  1. 在Activity的回调中手动将响应体转换为JSONObject:
Retrofit retrofit = new Retrofit.Builder()
    .baseUrl(API.BASE_URL)
    // 这里不需要移除GsonConverterFactory,只是暂时不用它处理这个接口的返回
    .addConverterFactory(GsonConverterFactory.create())
    .build();

YourApiService service = retrofit.create(YourApiService.class);
Call<ResponseBody> call = service.getRegisterUserData(dsn, id);

call.enqueue(new Callback<ResponseBody>() {
    @Override
    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
        if (response.isSuccessful() && response.body() != null) {
            try {
                // 将响应体字符串转换为Android原生JSONObject
                String responseStr = response.body().string();
                JSONObject jsonObject = new JSONObject(responseStr);
                // 在这里处理你的JSONObject数据
            } catch (IOException | JSONException e) {
                e.printStackTrace();
                // 处理解析异常
            }
        }
    }

    @Override
    public void onFailure(Call<ResponseBody> call, Throwable t) {
        // 处理请求失败逻辑
        t.printStackTrace();
    }
});

方案二:自定义ConverterFactory支持JSONObject

如果你的项目中有多个接口都需要返回JSONObject,不想每次都手动解析,可以自定义一个转换器,让Retrofit能自动将响应转换为Android原生JSONObject:

  1. 先创建一个自定义的ResponseBodyConverter:
public class JSONObjectConverter implements Converter<ResponseBody, JSONObject> {
    @Override
    public JSONObject convert(ResponseBody value) throws IOException {
        try {
            return new JSONObject(value.string());
        } catch (JSONException e) {
            throw new IOException("JSON parsing failed", e);
        } finally {
            value.close();
        }
    }
}
  1. 再创建对应的ConverterFactory:
public class JSONObjectConverterFactory extends Converter.Factory {
    public static JSONObjectConverterFactory create() {
        return new JSONObjectConverterFactory();
    }

    @Nullable
    @Override
    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
        // 当返回类型是JSONObject时,使用我们的自定义转换器
        if (type == JSONObject.class) {
            return new JSONObjectConverter();
        }
        return super.responseBodyConverter(type, annotations, retrofit);
    }
}
  1. 最后在构建Retrofit时添加这个自定义ConverterFactory(注意要放在GsonConverterFactory之前,这样会优先处理JSONObject类型的返回):
Retrofit retrofit = new Retrofit.Builder()
    .baseUrl(API.BASE_URL)
    .addConverterFactory(JSONObjectConverterFactory.create())
    .addConverterFactory(GsonConverterFactory.create())
    .build();
  1. 现在你的接口就可以直接返回Call<JSONObject>了:
@POST("testservice")
@FormUrlEncoded
Call<JSONObject> getRegisterUserData(
    @Header("x-dsn") String dsn,
    @Field("id") String id
);

注意事项

  • 方案一中,response.body().string()只能调用一次,因为调用后响应体的流会被关闭,所以要先把字符串存起来再处理。
  • 方案二中,自定义转换器要处理好异常,避免因为解析失败导致整个请求崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:18:53