• 网络框架OKHTTP使用场景全解析


    【本文版权归微信公众号"代码艺术"(ID:onblog)所有,若是转载请务必保留本段原创声明,违者必究。若是文章有不足之处,欢迎关注微信公众号私信与我进行交流!】

    一、引言

    说句实话,我之前一直在用 Jsoup 作为网络请求的框架首选,因为它使用简单、快捷,自带 HTML 文档解析,很适合用于爬虫这种场景。但是当我进入公司,涉及到网络请求场景的时候,更多的则是使用 OkHttp 框架。

    二、入门

    OkHttp 有哪些特点呢?根据官方说明总结如下:

    • 支持HTTP/2,HTTP/2通过使用多路复用技术在一个单独的TCP连接上支持并发,通过在一个连接上一次性发送多个请求来发送或接收数据。
    • 如果HTTP/2不可用,连接池复用技术也可以极大减少延时。
    • 默认支持GZIP,可以压缩下载体积。
    • 响应缓存可以完全避免网络重复请求。
    • 会从很多常用的连接问题中自动恢复。
    • 如果您的服务器配置了多个IP地址,当第一个IP连接失败的时候,OkHttp会自动尝试下一个IP
    • OkHttp还处理了代理服务器问题和SSL握手失败问题。

    使用 OkHttp 很容易。它的请求/响应 API 具有流畅的构建器和不变性,这源自于 OkHttp 大量使用了 Builder 模式构建 Request / Response 对象。同时,OkHttp 支持同步阻塞调用和带有回调的异步调用。

    三、使用

    导入依赖:

    <dependency>
        <groupId>com.squareup.okhttp3</groupId>
        <artifactId>okhttp</artifactId>
        <version>3.2.0</version>
    </dependency>
    

    GET请求:简单请求

    /**
     * GET请求:简单请求
     */
    @Test
    public void get() throws IOException {
        // 1.构建请求客户端,设置超时时间、代理等,可以理解为配置一个浏览器
        OkHttpClient okHttpClient = new OkHttpClient();
        // 2.构建请求实体,包括请求的URL、请求方法、请求头
        Request request = new Request.Builder()
                .url("http://www.baidu.com")
                .get()
                .build();
        // 3.浏览器发出请求,返回Response响应
        Response response = okHttpClient.newCall(request).execute();
        if (response.isSuccessful()) {
            System.out.println(response.body().string());
        } else {
            System.err.println(response);
        }
    }
    

    GET请求:异步回调

    /**
     * GET请求:异步回调请求
     */
    @Test
    public void get2() throws InterruptedException {
        // 1.构建请求客户端,设置超时时间、代理等,可以理解为配置一个浏览器
        OkHttpClient okHttpClient = new OkHttpClient();
        // 2.构建请求实体,包括请求的URL、请求方法、请求头
        Request request = new Request.Builder()
                .url("http://www.baidu.com")
                .get()
                .build();
        // 3.浏览器发出请求,返回Response响应
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                // 取消、连接问题或超时。由于网络在交换期间可能会失败,因此远程服务器可能在故障之前接受了请求。
                e.printStackTrace();
            }
    
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()) {
                    System.out.println(response.body().string());
                } else {
                    System.err.println(response);
                }
            }
        });
        Thread.sleep(3000);
    }
    

    GET请求:下载文件

    /**
     * GET请求:下载文件
     */
    @Test
    public void get3() throws IOException {
        // 1.构建请求客户端,设置超时时间、代理等,可以理解为配置一个浏览器
        OkHttpClient okHttpClient = new OkHttpClient();
        // 2.构建请求实体,包括请求的URL、请求方法、请求头
        Request request = new Request.Builder()
                .url("https://ystblog.com/assets/img/wechat.png")
                .get()
                .build();
        // 3.浏览器发出请求,返回Response响应
        Response response = okHttpClient.newCall(request).execute();
        if (response.isSuccessful()) {
            // 保存文件到本地
            File file = new File("image.png");
            try (InputStream inputStream = response.body().byteStream();
                 FileOutputStream fileOutputStream = new FileOutputStream(file)) {
                byte[] bytes = new byte[1024];
                int size;
                while ((size = inputStream.read(bytes)) > 0) {
                    fileOutputStream.write(bytes, 0, size);
                    fileOutputStream.flush();
                }
                System.out.println("文件保存在:" + file.getAbsolutePath());
            }
        } else {
            System.err.println(response);
        }
    }
    

    POST请求:发送JSON串

    【本文版权归微信公众号"代码艺术"(ID:onblog)所有,若是转载请务必保留本段原创声明,违者必究。若是文章有不足之处,欢迎关注微信公众号私信与我进行交流!】

    /**
     * POST请求:发送JSON串
     * <p>
     * MediaType.parse("application/json; charset=utf-8")
     * <p>
     * 该方式同样适用于发送任意单一内容:文字、文件、字节流等
     */
    @Test
    public void post() throws IOException {
        // 1.构建请求客户端,设置超时时间、代理等,可以理解为配置一个浏览器
        OkHttpClient okHttpClient = new OkHttpClient();
        // 2.构建请求实体,包括请求的URL、请求方法、请求头
        Request request = new Request.Builder()
                .url("http://www.baidu.com")
                .post(RequestBody.create(MediaType.parse("application/json; charset=utf-8"), "{}"))
                .build();
        // 3.浏览器发出请求,返回Response响应
        Response response = okHttpClient.newCall(request).execute();
        if (response.isSuccessful()) {
            System.out.println(response.body().string());
        } else {
            System.err.println(response);
        }
    }
    

    POST请求:发送二进制数据

    /**
     * POST请求:发送二进制数据
     * <p>
     * MediaType.parse("application/octet-stream")
     */
    @Test
    public void post4() throws IOException {
        // 1.构建请求客户端,设置超时时间、代理等,可以理解为配置一个浏览器
        OkHttpClient okHttpClient = new OkHttpClient();
        // 2.构建请求实体,包括请求的URL、请求方法、请求头
        Request request = new Request.Builder()
                .url("http://www.baidu.com")
                .post(RequestBody.create(MediaType.parse("application/octet-stream"), new File("image.png")))
                .build();
        // 3.浏览器发出请求,返回Response响应
        Response response = okHttpClient.newCall(request).execute();
        if (response.isSuccessful()) {
            System.out.println(response.body().string());
        } else {
            System.err.println(response);
        }
    }
    

    POST请求:发送文字表单

    /**
     * POST请求:发送文字表单
     * <p>
     * MediaType.parse("application/x-www-form-urlencoded")
     * <p>
     * 对键值对参数进行URL编码封装,也就是Query参数串:k1=v1&k2=v2&k3=v3
     */
    @Test
    public void post2() throws IOException {
        // 1.构建请求客户端,设置超时时间、代理等,可以理解为配置一个浏览器
        OkHttpClient okHttpClient = new OkHttpClient();
        // 2.构建请求实体,包括请求的URL、请求方法、请求头
        Request request = new Request.Builder()
                .url("http://www.baidu.com")
                .post(new FormBody.Builder().add("key", "value").build())
                .build();
        // 3.浏览器发出请求,返回Response响应
        Response response = okHttpClient.newCall(request).execute();
        if (response.isSuccessful()) {
            System.out.println(response.body().string());
        } else {
            System.err.println(response);
        }
    }
    

    POST请求:发送文件表单

    /**
     * POST请求:上传文件
     * <p>
     * MediaType.parse("multipart/form-data")
     */
    @Test
    public void post3() throws IOException {
        // 1.构建请求客户端,设置超时时间、代理等,可以理解为配置一个浏览器
        OkHttpClient okHttpClient = new OkHttpClient();
        // 2.构建请求实体,包括请求的URL、请求方法、请求头
        File file = new File("image.png");
        Request request = new Request.Builder()
                .url("https://imgkr.com/api/files/upload")
                .addHeader("user-agent", "Mozilla/5.0")
                .post(new MultipartBody.Builder()
                        .setType(MultipartBody.FORM)
                        .addFormDataPart("file", file.getName(), RequestBody.create(MediaType.parse("image/png"), file))
                        .build())
                .build();
        // 3.浏览器发出请求,返回Response响应
        Response response = okHttpClient.newCall(request).execute();
        if (response.isSuccessful()) {
            System.out.println(response.body().string());
        } else {
            System.err.println(response);
        }
    }
    

    四、链接

    OkHttp 官网:https://github.com/square/okhttp/

    版权声明

    【本文版权归微信公众号"代码艺术"(ID:onblog)所有,若是转载请务必保留本段原创声明,违者必究。若是文章有不足之处,欢迎关注微信公众号私信与我进行交流!】

  • 相关阅读:
    android AsyncTask
    android利用provider查询同一个数据库中没有对外暴露出来的表
    PowerProfile.java与power_profile.xml
    Java的动态绑定机制
    Activity Intent Flags及Task相关属性
    非阻塞socket调用connect, epoll和select检查连接情况示例
    Linux Epoll相关知识
    JAVA并发编程
    Activity生命周期(深入理解)
    Android线程间通信更新UI的方法(重点分析EventBus)
  • 原文地址:https://www.cnblogs.com/onblog/p/13036274.html
Copyright © 2020-2023  润新知