OkHttp实战注意的问题

1,265 阅读2分钟

1.The response body must be closed.

在官方文档中这样写道

Each response body is backed by a limited resource like a socket (live network responses) or an open file (for cached responses). Failing to close the response body will leak resources and may ultimately cause the application to slow down or crash.

Both this class and Response implement Closeable. Closing a response simply closes its response body. If you invoke Call.execute or implement Callback.onResponse you must close this body by calling any of the following methods:

Response.close()
Response.body().close()
Response.body().source().close()
Response.body().charStream().close()
Response.body().byteStream().close()
Response.body().bytes()
Response.body().string()

从上面论述可以得到结果,关闭response关闭response body即可,除了调用response的bytes()和string()方法,response body必须要显示的调用close方法

推荐使用下述方法进行response body的关闭

// 同步调用关闭response body
Call call = client.newCall(request);
try (Response response = call.execute()) {
... // Use the response.
}

// 异步调用关闭response body
Call call = client.newCall(request);
call.enqueue(new Callback() {
  public void onResponse(Call call, Response response) throws IOException {
    try (ResponseBody responseBody = response.body()) {
    ... // Use the response.
    }
  }

  public void onFailure(Call call, IOException e) {
  ... // Handle the failure.
  }
});

2.禁止OkHttp的自动重定向

final OkHttpClient client = new OkHttpClient().newBuilder()
                // 禁止 OkHttp 的重定向操作,我们自己处理重定向
                .followRedirects(false)
                .followSslRedirects(false)
                .cookieJar(new LocalCookieJar())
                .build();

3.OkHttp获取响应后再发送请求时可自动携带Cookie

参考

final OkHttpClient client = new OkHttpClient().newBuilder()
                // 禁止 OkHttp 的重定向操作,我们自己处理重定向
                .followRedirects(false)  
                .followSslRedirects(false)
                // 为OkHttp设置自动携带Cookie的功能
                .cookieJar(new LocalCookieJar())   
                .build();

//CookieJar是用于保存Cookie的
class LocalCookieJar implements CookieJar{
    List<Cookie> cookies;
    @Override
    public List<Cookie> loadForRequest(HttpUrl arg0) {
         if (cookies != null)
                return cookies;
            return new ArrayList<Cookie>();
    }

    @Override
    public void saveFromResponse(HttpUrl arg0, List<Cookie> cookies) {
        this.cookies = cookies;
    }
    
}
public void test() {
        final OkHttpClient client = new OkHttpClient().newBuilder()
                .followRedirects(false)
                .followSslRedirects(false)
                .cookieJar(new LocalCookieJar())
                .build();
        //构造一个POST请求
        RequestBody body = new FormBody.Builder().add("UserStyle", "student")
                .add("user", "xxx").add("password", "xxx").build();

        Request request = new Request.Builder().url("http://222.195.8.201/pass.asp").post(body).build();
        client.newCall(request).enqueue(new Callback() {

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                /**
                 * 如果不用CookieJar,那么就要自己去解析返回的Set-Cookie字段,解析之后通过addHeader("Cookie", cookie)
                 * 添加Cookie请求头
                 */
//              List<String> cookies =  response.headers("Set-Cookie");
//              String cookie = "";
//              for(int i=cookies.size()-1; i>=0; i--){
//                  cookie = cookie+ cookies.get(i).replace("path=/", "") + " ";
//              }

                //做GET请求
                Request redirectRequest = new Request.Builder().url("http://222.195.8.201/student/asp/Select_Success.asp")
//                    .addHeader("Cookie", cookie)
                        .build();
                //拿到登陆后操作的某个网页的内容
                Response response2 = client.newCall(redirectRequest).execute();
                String result = response2.body().string();
                System.out.println(result);
            }

            @Override
            public void onFailure(Call arg0, IOException arg1) {

            }
        });
    }