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;
    }
}

 

posted @ 2018-12-12 11:15  娜娜娜娜小姐姐  阅读(565)  评论(0编辑  收藏  举报