zoukankan      html  css  js  c++  java
  • OKHttp3学习

    转载 Okhttp3基本使用 基本使用——OkHttp3详细使用教程

    一、简介

    HTTP是现代应用常用的一种交换数据和媒体的网络方式,高效地使用HTTP能让资源加载更快,节省带宽。

    OkHttp是一个高效的HTTP客户端,它有以下默认特性:

    • 支持HTTP/2,允许所有同一个主机地址的请求共享同一个socket连接
    • 连接池减少,请求连接复用以提高效率
    • 透明的GZIP压缩减少响应数据的大小
    • 缓存响应内容,避免一些完全重复的请求
    • 当网络出现问题时,OkHttp 会自动重试一个主机的多个 IP 地址

      当网络出现问题的时候OkHttp依然坚守自己的职责,它会自动恢复一般的连接问题,如果你的服务有多个IP地址,当第一个IP请求失败时,OkHttp会交替尝试你配置的其他IP,OkHttp使用现代TLS技术(SNI, ALPN)初始化新的连接,当握手失败时会回退到TLS 1.0。

    注:

    • OkHttp 支持 Android 2.3 及以上版本Android平台, 对于 Java, JDK 1.7及以上.。
    • socket:网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。

    二、使用例子:

    讲解:

    Requests-请求:
      每一个HTTP请求中都应该包含一个URL,一个GET或POST方法以及Header或其他参数,当然还可以含特定内容类型的数据流。request一旦build()之后,便不可修改。

    Responses-响应:
      响应则包含一个回复代码(200代表成功,404代表未找到),Header和定制可选的body。

    OkHttpClient:
      OkHttpClient可以发送一个Http请求,并读取该Http请求的响应,它是一个生产Call的工厂。 此外,受益于一个共享的响应缓存/线程池/复用的连接等因素,绝大多数应用使用一个OkHttpClient实例,便可以满足整个应用的Http请求。

    三种创建实例的方法:

    • 创建一个默认配置OkHttpClient,可以使用默认的构造函数。
    • 通过new OkHttpClient.Builder()方法来一步一步配置一个OkHttpClient实例。
    • 如果要求使用现有的实例,可以通过newBuilder()方法来进行构造。
    OkHttpClient client = new OkHttpClient();
    OkHttpClient clientWith30sTimeout = client.Builder()
        .readTimeout(30, TimeUnit.SECONDS)
        .build();
    OkHttpClient client  = client.newBuilder().build();

    1.get请求方式

    1.1 get异步提交请求

    /**
     * get异步提交请求
     * @param url
     */
    public static void getAsyn(String url) {
        // 1.创建OkHttpClient对象
        OkHttpClient okHttpClient = new OkHttpClient();
        // 2.创建Request对象,设置一个url地址,设置请求方式。默认为get请求,可以不写。
        final Request request = new Request.Builder()
                .url(url)
                .get()
                .build();
        // 3.创建一个call对象,参数就是Request请求对象
        Call call = okHttpClient.newCall(request);
        // 4.请求加入调度,重写回调方法
        call.enqueue(new Callback() {
            // 请求失败执行的方法
            @Override
            public void onFailure(Call call, IOException e) {
                logger.info("getAsyn-call"+call);
                logger.info("getAsyn-IOException:"+e);
            }
            // 请求成功执行的方法
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                logger.info("getAsyn-response:"+response);
                System.out.println(response.body().string());
                System.out.println(response.body().byteStream());
                logger.info("call"+call);
            }
        });
    }

    1.2 get同步提交请求

    /**
     * get同步提交请求
     * @param url
     */
    public static void getSyn(String url) {
        // 1.创建OkHttpClient对象
        OkHttpClient okHttpClient = new OkHttpClient();
        // 2.创建Request对象,设置一个url地址,设置请求方式。
        final Request request = new Request.Builder().url(url).build();
        // 3.创建一个call对象,参数就是Request请求对象
        final Call call = okHttpClient.newCall(request);
        // 4.同步调用会阻塞主线程,这边在子线程进行
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    // 同步调用,返回Response,会抛出IO异常
                    Response response = call.execute();
                    logger.info("getSyn-response:"+response);
                    System.out.println(response.body().string());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    1.3 get异步下载文件

    /**
     * get异步下载文件
     * @param url
     */
    public static void getFile(String url) {
        // 1.创建OkHttpClient对象
        OkHttpClient okHttpClient = new OkHttpClient();
        // 2.创建Request对象,设置一个url地址,设置请求方式。
        Request request = new Request.Builder()
                .url(url)
                .get()
                .build();
        // 3.创建一个call对象,参数就是Request请求对象,重写回调方法。
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                logger.info("getFile-call"+call);
                logger.info("getFile-IOException:"+e);
            }
    
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                // 拿到字节流
                InputStream is = response.body().byteStream();
                int len = 0;
                // 设置下载图片存储路径和名称
                File file = new File("F:/img/","baidu.png");
    
                FileOutputStream fos = new FileOutputStream(file);
                byte[] buf = new byte[128];
                while ((len = is.read(buf)) != -1) {
                    fos.write(buf,0,len);
                }
                fos.flush();
                fos.close();
                is.close();
            }
        });
    }

    2.post请求方式

    2.1 post异步请求String

    /**
     * post异步请求String
     * @param url
     */
    public static void postString(String url) {
        // "类型,字节码"
        MediaType mediaType = MediaType.parse("application/json;charset=utf-8");
        // 1.创建OkHttpClient对象
        OkHttpClient okHttpClient = new OkHttpClient();
        String requestBody = "{name:nana}";
        // 3.创建Request对象,设置URL地址,将RequestBody作为post方法的参数传入
        Request request = new Request.Builder()
                .url(url)
                .post(RequestBody.create(mediaType,requestBody))
                .build();
    
        // 4.创建一个call对象,参数就是Request请求对象。请求加入调度,重写回调方法
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                logger.info("postString-call"+call);
                logger.info("postString-IOException:"+e);
            }
    
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                logger.info("postString-response:"+response);
                System.out.println(response.body().string());
                System.out.println(response.body().byteStream());
                logger.info("postString-call"+call);
            }
        });
    }

    2.2 post异步请求流

    /**
     * post异步请求流
     * @param url
     */
    public static void postStreaming(String url) {
        final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown;charset=utf-8");
        File file = new File("F:/img/baidu.png");
        try {
            FileInputStream fileInputStream = new FileInputStream(file);
    
            RequestBody requestBody = new RequestBody() {
                @Nullable
                @Override
                public MediaType contentType() {
                    return MEDIA_TYPE_MARKDOWN;
                }
    
                @Override
                public void writeTo(BufferedSink bufferedSink) throws IOException {
                    OutputStream outputStream = bufferedSink.outputStream();
                    int length = 0;
                    byte[] buffer = new byte[1024];
                    while ((length = fileInputStream.read(buffer)) != -1) {
                        outputStream.write(buffer,0,length);
                    }
                }
            };
            Request request = new Request.Builder().
                    url(url).
                    post(requestBody).
                    build();
            OkHttpClient okHttpClient = new OkHttpClient();
            okHttpClient.newCall(request).enqueue(new Callback() {
    
                @Override
                public void onFailure(Call call, IOException e) {
                    logger.info("postFlow-call"+call);
                    logger.info("postFlow-IOException:"+e);
                }
    
                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    logger.info("postFlow-response:"+response);
                    logger.info(response.protocol()+" "+response.code() + " " + response.message());
                    Headers headers = response.headers();
                    for (int i=0;i< headers.size();i++) {
                        System.out.println(headers.name(i)+":"+headers.value(i));
                    }
                    System.out.println(response.body().string());
                    logger.info("postFlow-call"+call);
                }
            });
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    
    }

    2.3 post异步上传Multipart文件

    /**
     * post异步上传Multipart文件
     * @param url
     */
    public static void postMultipart(String url) {
        OkHttpClient okHttpClient = new OkHttpClient();
        File file = new File("F:/img/","baidu.png");
        MediaType mediaType = MediaType.parse("image/png");
        RequestBody requestBody = new MultipartBody.Builder()
                // 设置表单类型
                .setType(MultipartBody.FORM)
                // 添加数据
                .addFormDataPart("name","nana")
                .addFormDataPart("file","baidu.png",RequestBody.create(mediaType,file))
                .build();
        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                logger.info("postFlow-call"+call);
                logger.info("postFlow-IOException:"+e);
            }
    
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                logger.info("postMultiportBody-response:"+response);
                System.out.println(response.body().string());
                logger.info("postMultiportBody-call"+call);
            }
        });
    }

    2.4 post异步请求文件

    /**
     * post异步请求文件
     * @param url
     */
    public static void postFile(String url) {
        MediaType mediaType = MediaType.parse("text/x-markdown;charset=utf-8");
        OkHttpClient okHttpClient = new OkHttpClient();
        File file = new File("F:/img/baidu.png");
        Request request = new Request.Builder()
                .url(url)
                .post(RequestBody.create(mediaType,file))
                .build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                logger.info("postFile-call"+call);
                logger.info("postFile-IOException:"+e);
            }
    
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                logger.info("postFile-response:"+response);
                logger.info(response.protocol()+" "+response.code() + " " + response.message());
                Headers headers = response.headers();
                for (int i=0;i< headers.size();i++) {
                    System.out.println(headers.name(i)+":"+headers.value(i));
                }
                System.out.println(response.body().string());
                System.out.println(response.body().byteStream());
                logger.info("postFile-call"+call);
            }
        });
    }

    2.5 post异步请求表单

    /**
     * post异步请求表单
     * @param url
     */
    public static void postForm(String url) {
        // 1.创建OkHttpClient对象
        OkHttpClient okHttpClient = new OkHttpClient();
        // 2.通过new FormBody()调用build方法,创建一个RequestBody,可以用add添加键值对
        RequestBody requestBody = new FormBody.Builder()
                .add("name","nana")
                .build();
        // 3.创建Request对象,设置URL地址,将RequestBody作为post方法的参数传入
        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();
        // 4.创建一个call对象,参数就是Request请求对象。请求加入调度,重写回调方法
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                if(e.toString().contains("closed")) {
                    // 主动取消的请情况下
                }
                logger.info("postForm-call"+call);
                logger.info("postForm-IOException:"+e);
            }
    
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                logger.info("postForm-response:"+response);
                logger.info(response.protocol()+" "+response.code() + " " + response.message());
                Headers headers = response.headers();
                for (int i=0;i< headers.size();i++) {
                    System.out.println(headers.name(i)+":"+headers.value(i));
                }
                System.out.println(response.body().string());
                System.out.println(response.body().byteStream());
                logger.info("postForm-call"+call);
            }
        });
    }

    2.6 post异步请求表单

    /**
     * post分块请求
     * @param url
     */
    public static void postMultiportBody(String url) {
        final String IMGUR_CLIENT_ID = "...";
        final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");
        OkHttpClient client = new OkHttpClient();
        MultipartBody body = new MultipartBody.Builder("Axad")
                .setType(MultipartBody.FORM)
                .addPart(
                        Headers.of("Content-Disposition","form-data;name='name'"),
                        RequestBody.create(null,"nana")
                )
                .addPart(
                        Headers.of("Content-Dispostion","form-data;name='image'"),
                        RequestBody.create(MEDIA_TYPE_PNG,new File("img.png"))
                )
                .build();
        Request request = new Request.Builder()
                .header("Authorization","Client-ID "+IMGUR_CLIENT_ID)
                .url(url)
                .build();
    
        Call call = client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                logger.info("postMultiportBody-call"+call);
                logger.info("postMultiportBody-IOException:"+e);
            }
    
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                logger.info("postMultiportBody-response:"+response);
                System.out.println(response.body().string());
                logger.info("postMultiportBody-call"+call);
            }
        });
    }

    2.7 post拦截器

    /**
     * post拦截器
     * @param url
     */
    public static void postInterceptor(String url) {
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .addInterceptor(new LoggerInterceptor())
                .build();
        Request request = new Request.Builder()
                .url(url)
                .header("User-Agent","OKHttp Example")
                .build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                logger.info("postInterceptor-call"+call);
                logger.info("postInterceptor-IOException:"+e);
            }
    
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                logger.info("postInterceptor-response:"+response);
                ResponseBody body = response.body();
                if (body != null) {
                    System.out.println(response.body().string());
                    body.close();
                }
                logger.info("postInterceptor-call:"+call);
            }
        });
    }
    import okhttp3.Interceptor;
    import okhttp3.Request;
    import okhttp3.Response;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import java.io.IOException;
    
    public class LoggerInterceptor implements Interceptor {
        private static final Logger logger = LoggerFactory.getLogger(LoggerInterceptor.class);
        private static final String TAG = "LoggingInterceptor";
        @Override
        public Response intercept(Chain chain) throws IOException {
            // 拦截请求,获取到该次请求的request
            Request request = chain.request();
    
            long startTime = System.nanoTime();
            logger.info(String.format("Sending request %s on %s%n%s",
                    request.url(),chain.connection(),request.headers()));
            // 执行本次网络请求操作返回response
            Response response = chain.proceed(request);
            long endTime = System.nanoTime();
            logger.info(String.format("Received response for %s in %.1fms%n%s",
                    response.request().url(),(endTime - startTime)/1e6d,response.headers()));
            return response;
        }
    }
  • 相关阅读:
    C# IP地址字符串和数值转换
    Xstream序列化实体
    异步线程及同步控制
    XML序列化与反序列化(转)
    C# Webserice 代理生成工具(WSDL)
    ASP.NET(C#)图片加文字、图片水印(转)
    异步导致UI句柄增加的解决办法
    终于找到WinForm自定义控件不能拖到IDE设计器容器的办法
    C# PropertyGrid控件应用心得(转载)
    GDI_图片半透明效果示例
  • 原文地址:https://www.cnblogs.com/nananana/p/10106004.html
Copyright © 2011-2022 走看看