【问题标题】:extracting values from JSON response从 JSON 响应中提取值
【发布时间】:2019-04-17 00:22:44
【问题描述】:

从休息服务我收到以下 json 响应

{"code":1,"message":"success","status":"success","users":[{"email":"qqq@aa.aa","name":"qq"},{"email":"dd@dd.dd","name":"dd"},{"email":"cc@vv.vv","name":"cc"},{"email":"qq@qq.qq","name":"qq"},{"email":"qq@qq.qq","name":"qq"}]}

当我尝试将其转换为 JSONObject 时,它会引发错误, 这就是我尝试提取 JSON 响应的方式,

jsonObject = new JSONObject(response.body().string());

错误是从上面的脚本中抛出的。错误如下,

E/AndroidRuntime: FATAL EXCEPTION: OkHttp Dispatcher
Process: com.example.ej.ziphiotest, PID: 21945
java.lang.IllegalStateException: closed
    at okio.RealBufferedSource.rangeEquals(RealBufferedSource.java:408)
    at okio.RealBufferedSource.rangeEquals(RealBufferedSource.java:402)
    at okhttp3.internal.Util.bomAwareCharset(Util.java:432)
    at okhttp3.ResponseBody.string(ResponseBody.java:174)
    at com.example.ej.ziphiotest.requests.UserRequest$1.onResponse(UserRequest.java:85)
    at okhttp3.RealCall$AsyncCall.execute(RealCall.java:153)
    at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
    at java.lang.Thread.run(Thread.java:818)

编辑:

这是请求:

final Request request = new Request.Builder()
            .header("key", params[0])
            .url(URL)
            .build();

    try {
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                call.cancel();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.code() == 200){
                    try {
                        jsonObject = new JSONObject(response.body().string());
                        restResponse = new RestResponse(jsonObject.getString("status"), jsonObject.getString("code"), jsonObject.getString("message"), null, jsonObject.getJSONArray("users"));
                        onTaskComplete.onTaskComplete(restResponse);
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }

            }
        });
    } catch (Exception e) {
        e.printStackTrace();
    }


}

我错过的地方。感谢您宝贵的时间

【问题讨论】:

  • 替换这个“jsonObject = new JSONObject(response.body().string());”用“jsonObject = new JSONObject(response);”
  • 对我来说,这似乎不像 json 错误。你能发布你的api调用代码吗
  • 您是否两次调用response.body().string();,我的意思是一次用于记录它,另一次用于转换为 JsonObject 并处理它?
  • @EJChathuranga 不要多次调用响应主体,因为它作为流读取而不存储在内存中参考:github.com/square/okhttp/issues/1240
  • @EJChathuranga 尝试将其存储在一个变量中,然后使用该变量,而不是 response.body().string() 代码。因为响应体可能很大,所以 OkHttp 不会将其存储在内存中,它会在您需要时将其作为来自网络的流读取。当你将 body 读取为 string() OkHttp 下载响应体并返回给你而不保留对字符串的引用,如果没有新的请求,它不能被下载两次。

标签: java android json rest


【解决方案1】:

问题是我在很短的时间内使用了两次response.body().string()。 AS @Firoz Memon 在 cmets 中说。

尝试将其存储在一个变量中,然后使用该变量,而不是 response.body().string() 代码。因为响应体可能很大,所以 OkHttp 不会将其存储在内存中,它会在您需要时将其作为来自网络的流读取。当你将 body 读取为 string() 时,OkHttp 下载响应体并返回给你,而不保留对字符串的引用,如果没有新的请求,它不能被下载两次。

复制自@Firoz Memon 上面的评论。

原文参考:https://github.com/square/okhttp/issues/1240

【讨论】:

    【解决方案2】:

    首先解析对象,然后像这样解析对象数组:
    不要尝试直接使用 response.body.string() 。就像下面这样使用:

    ResponseBody responseBody = response.body();
    String content = responseBody.string();
    // Do something with "content" variable
    

    原因: body的字符串是存储在内存中的变量内容,所以我们不需要关心状态是否关闭。

     JSONObject jsonObject = new JSONObject(content);
        JSONArray jsonArray =jsonObject.getJSONArray("users");
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-03
      • 1970-01-01
      • 2022-07-02
      • 2020-07-28
      相关资源
      最近更新 更多