An HTTP & HTTP/2 client for Android and Java applications
引用自官方文檔java
什麼都無論,先上個代碼。敲完再說。git
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); } } });
上面的圖中顯示了response.body()
能夠獲得的數據類型。在上面的例子中咱們使用了string()
來獲得了相應的字符串數據。
須要注意的是這裏的回調不在主線程.若是須要更新UI。咱們還須要切換到主線程進行操做。github
這是一個異步調用的例子。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
的時候,使用到了Builder
設計模式。只須要簡單的鏈式調用配置好請求參數。以下:app
Request request = new Request.Builder().url(PATH) .header("User-Agent", "my-agent") .addHeader("Accept-Language", "zh-cn") .get() .build();
header
和addHeader
用來添加頭部字段的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.Builder
的set()
,一個是使用的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
設置,確定只有一個嘛。函數
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 { } });
將上面的請求經過抓包工具抓取後,下圖即爲本次的請求。工具
ResponseBody
是一個抽象類。在okhttp
中的子類有FormBody
和MultipartBody
。 咱們能夠經過靜態方法create
來構建一個ResponseBody
。
ResponseBody
內部的create
能夠經過三中方式構建。固然了。咱們也能夠模仿官方的crete
方法來構建本身的ResponseBody
來上傳制定類型的文件。
咱們經過MediaType
來指定咱們上傳文件的類型。好比上面代碼中的"application/json; charset=utf-8"
就是咱們上傳的內容的類型。
當咱們有什麼文件想要提交,可是不知道key
是什麼的時候能夠看MIME 參考手冊
用來提交一些表單數據。經過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
中的一些個類型。
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");