我正在尝试使用 Retrofit2 从每行一个流式传输 JSON 对象的 API 中进行消费。 响应看起来像这样
{"key":" value", ...}
{"key":" value", ...}
{"key":" value", ...}
{"key":" value", ...}
{"key":" value", ...}
{"key":" value", ...}
我尝试使用 Gson 转换器并将 lenient 设置为 true,以便它可以支持 json 多行对象,如下所示:
Gson gson = new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
.setLenient()
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(okHttpClient)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
还有我的API接口,我尝试过这个
public interface Api {
@Streaming
@POST("/stream")
@Headers({"accept: application/stream+json", "content-type: application/json"})
Call<Response>
generateStream2(@Body Request request);
}
但似乎 Gson 转换器无法消耗整个响应,我在尝试读取响应时遇到
JSON document was not fully consumed.
异常。
还尝试使用
Call<List<Response>>
但 gson 转换器失败,表示它期望 [
但得到了 {
。
有没有办法自动生成/转换这些对象的列表?
我没有一个很好的解决方案,只接受字符串响应,然后手动将行转换为我的对象。所以我的
Api.java
就变成了这样:
public interface Api {
@Streaming
@POST("/stream")
@Headers({"accept: application/stream+json", "content-type: application/json"})
Call<String>
generateStream2(@Body Request request);
}
然后当收到响应时像这样解析它
Gson gson = new Gson();
api.generateStream2(request).enqueue(new retrofit2.Callback<String>() {
@Override public void onResponse(Call<String> call, retrofit2.Response<String> response) {
String[] lines = response.body().split("\n");
for(String line: lines) {
Response resp = gson.fromJson(line, Response.class);
}
}
}