OkHttp

作者: yuanzicheng | 来源:发表于2017-11-01 18:37 被阅读137次

    1.OkHttp是什么?

    OkHttp是一个强大易用的Http请求库,对比HttpURLConnectionHttpClient,OkHttp功能更强、效率更高、解决方案更完善。

    2.如何使用OkHttp?

    2.1 添加依赖
    compile('com.squareup.okhttp3:okhttp:3.9.0')
    
    2.2 创建请求OkHttp客户端
    OkHttpClient okHttpClient = new OkHttpClient();
    
    2.3 创建请求OkHttp请求
    Request request = new Request.Builder().url("http://localhost:8080/users/").build();
    
    2.4 执行请求,接收响应
    Response response = okHttpClient.newCall(request).execute();
    if(response.isSuccessful()){
        System.out.println(JSONObject.toJSONString(response.body().string()));
    }
    

    当然,以上过程仅仅是使用了OkHttp默认的同步(阻塞)的GET请求方式,OkHttp还支持异步(非阻塞)的请求方式,还支持POST、PUT、DELETE等类型的请求。

    3.异步请求

    同步请求调用excute()方法,异步请求调用enqueue()方法,并实现Callback接口即可。

    Request request = new Request.Builder().url("http://localhost:8080/users/").get().build();
    OkHttpClient okHttpClient = new OkHttpClient();
    okHttpClient.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
        }
        
        @Override
        public void onResponse(Call call, Response response) throws IOException {
            if(response.isSuccessful()){
                System.out.println(response.body().string());
            }
        }
    });
    

    4.非GET请求

    非GET请求需要指定请求体RequestBody的媒体格式Content-Type,常见的媒体格式如下:

    Content-Type 说明
    text/html HTML格式
    text/plain 纯文本格式
    text/xml XML格式
    image/gif gif图片格式
    image/jpeg jpg图片格式
    image/png png图片格式
    application/xhtml+xml XHTML格式
    application/xml XML数据格式
    application/atom+xml Atom XML聚合格式
    application/json JSON数据格式
    application/pdf pdf格式
    application/msword Word文档格式
    application/octet-stream 二进制流数据(如文件下载)
    application/x-www-form-urlencoded <form encType=””>中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)
    multipart/form-data 需要在表单中进行文件上传时使用该格式
    4.1 POST、PUT、DELETE请求
    MediaType mediaType = MediaType.parse("application/json; charset=utf-8")
    RequestBody requestBody = RequestBody.create(mediaType , "json content");
    //POST
    Request request = new Request.Builder().url("http://localhost:8080/users/").post(requestBody).build();
    //PUT
    //Request request = new Request.Builder().url("http://localhost:8080/users/").put(requestBody).build();
    //DELETE
    //Request request = new Request.Builder().url("http://localhost:8080/users/").delete(requestBody).build();
    OkHttpClient okHttpClient = new OkHttpClient();
    Response response = okHttpClient.newCall(request).execute();
    if(response.isSuccessful()){
        System.out.println(JSONObject.toJSONString(response.body().string()));
    }
    
    4.2 从流生成RequestBody
    
    
    4.3 从文件生成RequestBody
    MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
    File file = new File("user.json");
    RequestBody requestBody = RequestBody.create(mediaType, file);
    Request request = new Request.Builder().url("http://localhost:8080/users/").post(requestBody).build();
    
    4.4 提交表单
    MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
    RequestBody requestBody = new FormBody.Builder()
                    .add("param1", "value1")
                    .add("param2","value2")
                    .build();
    Request request = new Request.Builder().url("http://localhost:8080/users/").post(requestBody).build();
    
    4.5 分块请求

    OkHttp提供了MultipartBody.Builder()来构建复杂的请求体, 分块请求体中每块请求都是一个请求体。

    RequestBody requestBody = new MultipartBody.Builder()
                    .setType(MultipartBody.FORM)
                    .addFormDataPart("param", "value")
                    .addFormDataPart("image", "test.png",RequestBody.create(MediaType.parse("image/png"), new File("test.png")))
                    .build();
    Request request = new Request.Builder()
                    .url("http://localhost:8080/users/")
                    .post(requestBody)
                    .build();
    

    5.请求头

    Request.Builder()提供了header()及addHeader()来设置和添加请求头,其中header()会移除已有的相同name的请求头,addHeader()会添加新的请求头,如果请求头的name已经存在,则该name对应多个value。

    Request request = new Request.Builder()
                    .header("k1","v1")
                    .addHeader("k2","v2")
                    .url("http://localhost:8080/users/")
                    .post(requestBody)
                    .build();
    

    6.响应头

    Response提供了header()方法获取单值响应头,header()可以获取多值响应头。

    Request request = new Request.Builder()..url("http://localhost:8080/users/").post(requestBody).build();
    OkHttpClient okHttpClient = new OkHttpClient();
    Response response = okHttpClient.newCall(request).execute();
    if(response.isSuccessful()){
        System.out.println(response.header("Server"));
        System.out.println(response.headers("Vary"));
    }
    

    7.缓存

    OkHttp提供了GET方式请求的缓存功能。

    OkHttpClient okHttpClient = new OkHttpClient();
    File directory = new File("指定缓存目录");
    long maxSize = 10 * 1024 * 1024; //10MiB
    Cache cache = new Cache(directory,maxSize);
    OkHttpClient client = okHttpClient.newBuilder().cache(cache).build();
    

    特别注意:使用缓存的时候,一定要使用同一个OkHttpClient,即OkHttpClient仅初始化一次,重复使用。

    8.超时

    OkHttp支持连接超时、请求(写)超时和响应(读)超时。

    OkHttpClient client = new OkHttpClient.Builder()
            .connectTimeout(10, TimeUnit.SECONDS)
            .writeTimeout(10, TimeUnit.SECONDS)
            .readTimeout(30, TimeUnit.SECONDS)
            .build();
    

    9.取消请求

    OkHttp中有一个Call的概念,同步执行请求使用call.excute(),异步执行请求使用call.enqueue(),Call提供了cancel()方法来取消请求,但如果一个线程正在写请求或者读响应, 将会引发IOException。取消请求在Android中用得较多,比如:用户刷新了页面等待几秒后发现数据还未加载,就退出了该界面,此时取消加载数据的请求是比较合适的。

    OkHttpClient client = new OkHttpClient();
    Call call = client.newCall(request);
    Response response = call.execute();
    //取消请求
    call.cancel();
    

    参考:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0106/2275.html

    相关文章

      网友评论

          本文标题:OkHttp

          本文链接:https://www.haomeiwen.com/subject/oogauxtx.html