OkHttp使用

配置

compile 'com.squareup.okhttp3:okhttp:3.4.1'

GET

首先是以同步的方式执行请求

//创建一个request
Request request = new Request.Builder()
        .url(url)
        .build();

Response response = client.newCall(request).execute();

if (response.isSuccessful()) {  //请求成功
    Log.d(TAG, "testGet: " + response.body().string());
} else {
    throw new IOException("" + response.code());
}

以上就是执行GET请求的方法。

  1. 构造一个Request对象,参数最起码有个url,当然你可以通过Request.Builder设置更多的参数比如:header、method等。
  2. 通过request的对象去构造得到一个Call对象,类似于将你的请求封装成了任务,既然是任务,就会有execute()和cancel()等方法。
  3. 当前我们使用的是同步的方法,即调用call的execute()方法。若希望以异步的方式去执行请求,我们可以调用call.enqueue,将call加入调度队列,然后等待任务执行完成,我们在Callback中即可得到结果。
  4. onResponse回调的参数是response,一般情况下,比如我们希望获得返回的字符串,可以通过response.body().string()获取;如果希望获得返回的二进制字节数组,则调用response.body().bytes();如果你想拿到返回的inputStream,则调用response.body().byteStream()。
  5. 图片下载,通过回调的Response拿到byte[]然后decode成图片;文件下载,就是拿到inputStream做写文件操作。

异步执行请求

call.enqueue(new Callback()
{
    //请求失败
    @Override
    public void onFailure(Request request, IOException e)
    {

    }

    //得到响应时
    @Override
    public void onResponse(final Response response) throws IOException
    {
        //String htmlStr =  response.body().string();
    }
});

为Request添加请求头

 Request request = new Request.Builder()
         .url("http://www.baidu.com")
         .addHeader("User-Agent","android")
         .header("Content-Type","text/html; charset=utf-8")
         .build();

若想要为GET请求添加参数的话可以使用HttpUrl类来构造url

HttpUrl.Builder urlBuilder = HttpUrl.parse(url).newBuilder();
urlBuilder.addQueryParameter("KEY", "VALUE");
HttpUrl httpUrl = urlBuilder.build();

POST

post请求的执行也可以同步或者异步,参考GET请求。简便起见,这里默认用同步方法。

POST 提交json字符串

设置MediaType

MediaType mediaType = Medi2aType.parse("application/json; charset=utf-8");

执行post请求

private Response post(String url, String json) throws IOException {
    RequestBody requestBody = RequestBody.create(mediaType, json);
    Request request = new Request.Builder()
            .url(url)
            .post(requestBody)
            .build();

    Response response = client.newCall(request).execute();
        return response;
}
  1. 通过RequestBody.create(MediaType contentType, String content)方法来构造RequestBody, contentType代表了上传内容的类型,content即上传的json字符串
  2. 使用Request的post方法来提交请求体RequestBody

POST 提交键值对

很多时候我们需要向服务器提交键值对。这是构造RequestBody的方法就与上面说的不同了。当然,这里介绍的时OkHttp3的方法
1. 通过FormBody.Builder()创建一个构造器,它的add()方法添加键值对,再通过build方法来构造一个FormBody。
2. FormBody的父类为RequestBody,所以我们可以将FormBody作为请求体使用。

RequestBody formBody = new FormBody.Builder()
        .add("name1", "value1")
        .add("name2", "value2")
        .build();

POST 以流的形式

public static final MediaType MEDIA_TYPE_MARKDOWN
      = MediaType.parse("text/x-markdown; charset=utf-8");

  private final OkHttpClient client = new OkHttpClient();

  public void run() throws Exception {
    RequestBody requestBody = new RequestBody() {
      //设置ContentType
      @Override
      public MediaType contentType() {
        return MEDIA_TYPE_MARKDOWN;
      }

      @Override
      public void writeTo(BufferedSink sink) throws IOException {
        sink.writeUtf8("Numbers\n");
        sink.writeUtf8("-------\n");
        for (int i = 2; i <= 997; i++) {
          sink.writeUtf8(String.format(" * %s = %s\n", i, (i)));
        }
      }

      private String factor(int n) {
        for (int i = 2; i < n; i++) {
          int x = n / i;
          if (x * i == n) return factor(x) + " × " + i;
        }
        return Integer.toString(n);
      }
    };

    Request request = new Request.Builder()
        .url("https://api.github.com/markdown/raw")
        .post(requestBody)
        .build();

    Response response = client.newCall(request).execute();
    if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

    System.out.println(response.body().string());
  }

这里直接向Buffered Sink中写入流,若更喜欢使用OutputStream,请使用BufferedSink.outputStream()

POST 上传文件

public static final MediaType MEDIA_TYPE_MARKDOWN
      = MediaType.parse("text/x-markdown; charset=utf-8");

  private final OkHttpClient client = new OkHttpClient();

  public void run() throws Exception {
    File file = new File("README.md");

    Request request = new Request.Builder()
        .url("https://api.github.com/markdown/raw")
        .post(RequestBody.create(MEDIA_TYPE_MARKDOWN, file))
        .build();

    Response response = client.newCall(request).execute();
    if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

    System.out.println(response.body().string());
  }

若不确定文件的类型,可通过以下方法获得文件类型

private static final MediaType MEDIA_TYPE = MediaType.parse(judgeType(fileName);
private String judgeType(String path) {
        FileNameMap fileNameMap = URLConnection.getFileNameMap();
        String contentTypeFor = fileNameMap.getContentTypeFor(path);
        if (contentTypeFor == null) {
            contentTypeFor = "application/octet-stream";
        }
        return contentTypeFor;
    }

POST 多种类型的body

通过MultipartBody.addPart(),MultipartBody.addFormDataPart()实现。每个Part都是它所属的RequestBody的一个请求体,因此,它们也可以拥有自己的headers。通过MultipartBody.setType()方法,可以设置MultipartBody的类型

private static final String IMGUR_CLIENT_ID = "...";
  private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");

  private final OkHttpClient client = new OkHttpClient();

  public void run() throws Exception {
    // Use the imgur image upload API as documented at https://api.imgur.com/endpoints/image
    RequestBody requestBody = new MultipartBody.Builder()
        .setType(MultipartBody.FORM)
        .addFormDataPart("title", "Square Logo")
        .addFormDataPart("image", "logo-square.png",
            RequestBody.create(MEDIA_TYPE_PNG, new File("website/static/logo-square.png")))
        .build();

    Request request = new Request.Builder()
        .header("Authorization", "Client-ID " + IMGUR_CLIENT_ID)
        .url("https://api.imgur.com/3/image")
        .post(requestBody)
        .build();

    Response response = client.newCall(request).execute();
    if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

    System.out.println(response.body().string());
  }

提取响应头

典型的HTTP头 像是一个Map<String, String>每个字段都有一个或没有值。但是一些头允许多个值,像Guava的Multimap。例如:HTTP响应里面提供的Vary响应头,就是多值的。OkHttp的api试图让这些情况都适用。
当写请求头的时候,使用header(name, value)可以设置唯一的name、value。如果已经有值,旧的将被移除,然后添加新的。使用addHeader(name, value)可以添加多值(添加,不移除已有的)。
当读取响应头时,使用header(name)返回最后出现的name、value。通常情况这也是唯一的name、value。如果没有值,那么header(name)将返回null。如果想读取字段对应的所有值,使用headers(name)会返回一个list。

参考

Android OkHttp完全解析 是时候来了解OkHttp了
OkHttp使用进阶 译自OkHttp Github官方教程
okhttp教程——起步篇
OkHttp使用教程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值