Java 从JSON响应中提取值

Java 从JSON响应中提取值,java,android,json,rest,Java,Android,Json,Rest,我从rest服务收到以下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"}]} 当我试图

我从rest服务收到以下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();
    }


}

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

首先解析对象,然后像这样解析对象数组:
不要试图直接使用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");

问题是我在很短的时间内使用了两次
response.body().string()
。正如评论中所说

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

抄袭自上面的评论


原始参考:

将这个“jsonObject=new-jsonObject(response.body().string());”替换为“jsonObject=new-jsonObject(response);”在我看来,它不像json错误。你能发布你的api调用代码吗你正在调用
response.body().string()两次,我的意思是一次用于记录它,另一次用于转换为JsonObject并处理它?@EJChathuranga不要多次调用响应体,因为它是作为流读取的,而不是存储在内存引用中:@EJChathuranga尝试将其存储在变量中,然后使用变量,而不是
response.body().string()
代码。因为响应体可能很大,所以OkHttp不会将其存储在内存中,所以当您需要时,它会将其作为流从网络中读取。当您将正文作为字符串读取()时,OkHttp将下载响应正文并将其返回给您,而不保留对该字符串的引用,在没有新请求的情况下无法下载两次。