如何在 Retrofit2 中预解析 JSON 结果(在发送到 GsonConverterFactory 之前)

How to preparse JSON results in Retrofit2 (before sending to GsonConverterFactory)

我正在尝试使用 retrofit2 和 GSON 消耗 JSON。

以下是服务器提供的响应。请注意,"d" 的值是一个有效的 JSON 字符串(删除斜杠后)。

{"d": "[{\"Number\":\"2121\",\"NumberOfAppearances\":2,\"Prizes\":
[{\"DrawDate\":\"\/Date(1439654400000)\/\",\"PrizeCode\":\"S\"}, {\"DrawDate\":\"\/Date(874771200000)\/\",\"PrizeCode\":\"S\"}]}]"}

有没有办法在调用 retrofitService 期间使用 retrofit2 来预解析 json 以获取 d 值中的对象?

Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            //is there anything i can do here to do preparsing of the results?
            .addConverterFactory(GsonConverterFactory.create())
            .build();  

IQueryLocations = retrofit.create(IMyQuery.class);

//currently GsonResults is the string value of d, instead of the JSON objects
Call<GsonResult> result = IMyQuery.doQuery("2121");

理想情况下,我喜欢在 addConverterFactory 之前插入一个方法调用来进行预解析

预解析方法的输出类似于以下内容:

{"d": [{"Number":"2121","NumberOfAppearances":2,"Prizes":
[{"DrawDate": 1439654400000,"PrizeCode":"S"}, {"DrawDate": 874771200000,"PrizeCode":"S"}]}]}

排除双引号需要使用GsonBuilder提供的excludeFieldsWithoutExposeAnnotation()

例如:

Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();

Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            // Add Gson object
            .addConverterFactory(GsonConverterFactory.create(gson))
            .build();  

希望对您有所帮助。

这不是您理想的解决方案,但您可以return结果数据的包装器:

class WrappedGsonResult {
    private static final Gson GSON = new Gson();

    @SerializedName("d")
    private String data;

    GsonResult() {}

    public GsonResult getData() {
        return GSON.fromJson(this.data, GsonResult.class);
    }
}

然后:

Call<WrappedGsonResult> result = IMyQuery.doQuery("2121");
result.enqueue(new Callback() {
    @Override
    public void onResponse(final Call<WrappedGsonResult> call, final Response<WrappedGsonResult> response) {
        if (response.isSuccessful()) {
            GsonResult result = response.body().getData();
            // ...
        } else {
            // ...
        }
    }

    // ...
});