OkHttp3學習(一):基本使用

An HTTP & HTTP/2 client for Android and Java applications
引用自官方文檔java

什麼都無論,先上個代碼。敲完再說。git

GET

OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .get()
                .url(PATH)
                .build();
        client.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()) {
                    String string = response.body().string();
                    Log.i(TAG, "onResponse: "+string);
                }
            }
        });

clipboard.png

上面的圖中顯示了response.body()能夠獲得的數據類型。在上面的例子中咱們使用了string()來獲得了相應的字符串數據。
須要注意的是這裏的回調不在主線程.若是須要更新UI。咱們還須要切換到主線程進行操做。github

POST

這是一個異步調用的例子。json

MediaType jsonType = MediaType.parse("application/json; charset=utf-8");
        OkHttpClient client = new OkHttpClient();
        String jsonStr = new Gson().toJson(mPerson);
        RequestBody body = RequestBody.create(jsonType,jsonStr);
        Request request = new Request.Builder()
                .post(body)
                .url(PATH)
                .build();
        client.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()){
                   String string = response.body().string();
                   Log.i(TAG, "post: "+string);
               }
           }
        });

請求大體過程

咱們每次作請求的時候都要有一個OkHttpClient實體,用來構建咱們的一次請求。而Request類用來設置咱們請求須要的參數,以後咱們就能夠經過client來發送一個請求了。在上面的例子中,咱們將請求加入到了一個請求隊列中(enqueue)。最後咱們就獲得了此次請求的響應response了。設計模式

Request

在構建Request的時候,使用到了Builder設計模式。只須要簡單的鏈式調用配置好請求參數。以下:app

Request request = new Request.Builder().url(PATH)
                .header("User-Agent", "my-agent")
                .addHeader("Accept-Language", "zh-cn")
                .get()
                .build();

header && addHeader

headeraddHeader用來添加頭部字段的key-value對。異步

/**
     * Sets the header named {@code name} to {@code value}. If this request already has any headers
     * with that name, they are all replaced.
     */
    public Builder header(String name, String value) {
      headers.set(name, value);
      return this;
    }
    /**
     * Adds a header with {@code name} and {@code value}. Prefer this method for multiply-valued
     * headers like "Cookie".
     *
     * <p>Note that for some headers including {@code Content-Length} and {@code Content-Encoding},
     * OkHttp may replace {@code value} with a header derived from the request body.
     */
    public Builder addHeader(String name, String value) {
      headers.add(name, value);
      return this;
    }

咱們看到,這兩個函數底層一個是使用的Header.Builderset(),一個是使用的add().在繼續往裏看:ide

/**
     * Set a field with the specified value. If the field is not found, it is added. If the field is
     * found, the existing values are replaced.
     */
    public Builder set(String name, String value) {
      checkNameAndValue(name, value);
      removeAll(name);
      addLenient(name, value);
      return this;
    }
    
      /** Add a field with the specified value. */
    public Builder add(String name, String value) {
      checkNameAndValue(name, value);
      return addLenient(name, value);
    }

這就很清晰了。很明顯了。set()調用了removeAll(key)方法來刪除以前設置了同名的key。而add並無刪除。其實從名字咱們就能夠看出來。add就是添加嘛。set設置,確定只有一個嘛。函數

RequestBody

OkHttpClient client =new OkHttpClient();
        MediaType parse = MediaType.parse("application/json; charset=utf-8");
        RequestBody body = RequestBody.create(parse,new Gson().toJson(mPerson));
        Request request = new Request.Builder().url(PATH)
                .header("User-Agent", "my-agent")
                .addHeader("Accept-Language", "zh-cn")
                .post(body)
                .build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {

            }
        });

將上面的請求經過抓包工具抓取後,下圖即爲本次的請求。
clipboard.png工具

ResponseBody是一個抽象類。在okhttp中的子類有FormBodyMultipartBody。 咱們能夠經過靜態方法create來構建一個ResponseBody

clipboard.png

ResponseBody內部的create能夠經過三中方式構建。固然了。咱們也能夠模仿官方的crete方法來構建本身的
ResponseBody來上傳制定類型的文件。
咱們經過MediaType來指定咱們上傳文件的類型。好比上面代碼中的"application/json; charset=utf-8"就是咱們上傳的內容的類型。
當咱們有什麼文件想要提交,可是不知道key是什麼的時候能夠看MIME 參考手冊

FormBody

用來提交一些表單數據。經過FormBody.Builder來添加表單數據。以下所示:

OkHttpClient client = new OkHttpClient();
        FormBody formBody = new FormBody.Builder()
                .add("username", "jason")
                .add("password", "magicer")
                .build();
        Request request = new Request.Builder()
                .post(formBody)
                .addHeader("User-Agent", "Apple")
                .build();
        Response response = client.newCall(request).execute();

FromBody中,查看其源碼咱們能夠看到FormBody設置的Content-Type"application/x-www-form-urlencoded".也就是普通表單數據。

private static final MediaType CONTENT_TYPE =
      MediaType.parse("application/x-www-form-urlencoded");

MultipartBody

如下是MultipartBody中的一些個類型。

public static final MediaType MIXED = MediaType.parse("multipart/mixed");
public static final MediaType ALTERNATIVE = MediaType.parse("multipart/alternative");
public static final MediaType DIGEST = MediaType.parse("multipart/digest");
public static final MediaType PARALLEL = MediaType.parse("multipart/parallel");
public static final MediaType FORM = MediaType.parse("multipart/form-data");
相關文章
相關標籤/搜索