Get異步請(qǐng)求
第一步,OkHttpClient的初始化
// 直接初始化,使用所有默認(rèn)配置
OkHttpClient okHttpClient = new OkHttpClient();
// 配置一些信息進(jìn)入OkHttpClient
mOkHttpClient = new OkHttpClient().newBuilder()
.connectTimeout(REQUEST_TIME, TimeUnit.SECONDS)
.readTimeout(REQUEST_TIME, TimeUnit.SECONDS)
.writeTimeout(REQUEST_TIME, TimeUnit.SECONDS)
.addInterceptor(new RetryInterceptor(2))
.addInterceptor(new LoggerInterceptor())
.build();
第二步,初始化Request
Request request = new Request.Builder().url(url).build();
其中,url為請(qǐng)求的網(wǎng)絡(luò)地址。
第三步,進(jìn)行異步請(qǐng)求
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
ResponseBody body = response.body();
if (body != null) {
Log.e(TAG, "onResponse: " + body.string());
}
}
});
需要注意的是:
body.string()方法只能調(diào)用一次,第二次調(diào)用會(huì)報(bào)一個(gè)非法狀態(tài)異常java.lang.IllegalStateException: closed
添加頭信息
很多時(shí)候請(qǐng)求需要對(duì)身份進(jìn)行驗(yàn)證,頭信息中添加相應(yīng)的健值對(duì)使得能夠通過(guò)服務(wù)器端的身份驗(yàn)證。
Request request = new Request.Builder().addHeader().build();
可以在初始化request的時(shí)候塞入頭信息,addHeader方法可以為相同鍵名添加多個(gè)值,header方法會(huì)覆蓋掉原來(lái)的值。
Post異步請(qǐng)求
post請(qǐng)求多了用RequestBody提交表單數(shù)據(jù)的步驟。
初始化RequestBody(第一種方式)
RequestBody默認(rèn)有兩個(gè)實(shí)現(xiàn)子類FormBody、MultipartBody,普通的表單數(shù)據(jù)提交。
RequestBody requestBody = new FormBody.Builder()
.add("name", "value")
.build();
通過(guò)add方法把需要提交的數(shù)據(jù)用健值對(duì)的形式提交至服務(wù)器。有人說(shuō)我想提交整個(gè)json字符串怎么辦呢?在第二種方式中,待會(huì)兒會(huì)講到。
MultipartBody表單,可以上傳文件和圖片至服務(wù)器。
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
//.addFormDataPart("","")
.addPart(Headers.of("Content-Disposition", "form-data;name =\"file\";filename=\"img.png\"")
, RequestBody.create(MediaType.parse("image/png"), file))
.build();
通過(guò)查看源碼,addFormDataPart與addPart最終殊途同歸,addPart可以自定義頭信息,而addFormDataPart也可以,只是需要一個(gè)一個(gè)添加;
// 源碼
public static Part createFormData(String name, @Nullable String filename, RequestBody body) {
if (name == null) {
throw new NullPointerException("name == null");
}
StringBuilder disposition = new StringBuilder("form-data; name=");
appendQuotedString(disposition, name);
if (filename != null) {
disposition.append("; filename=");
appendQuotedString(disposition, filename);
}
return create(Headers.of("Content-Disposition", disposition.toString()), body);
}
Headers.of()方法對(duì)參數(shù)的個(gè)數(shù)有要求,必須是偶數(shù)個(gè)數(shù),最終以健值對(duì)的形式填入到請(qǐng)求頭信息中。
初始化RequestBody(第二種方式)
MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json");
RequestBody requestBody = RequestBody.create(MEDIA_TYPE_JSON, obj.toString());
create方法第一個(gè)參數(shù)為網(wǎng)絡(luò)協(xié)議的消息頭里的Content-Type,一般情況下以下幾種類型較為常見(jiàn):
application/x-www-form-urlencoded
multipart/form-data
text/plain
application/json
application/x-www-form-urlencoded:瀏覽器標(biāo)準(zhǔn)的編碼格式,支持最為普遍,提交數(shù)據(jù)以健值對(duì)形式提交;
multipart/form-data:提交的數(shù)據(jù)會(huì)被分隔符隔開(kāi),并且會(huì)加上一些Content-Disposition屬性。
application/json:以json格式進(jìn)行數(shù)據(jù)提交。
第二個(gè)參數(shù)就是一個(gè)json字符串,標(biāo)準(zhǔn)格式的json字符串可以直接傳遞進(jìn)入,比如:
{"CityId":18,"CityName":"changsha","ProvinceId":27,"CityOrder":1}
初始化request
通過(guò)post方法把相應(yīng)的RequestBody對(duì)象傳遞進(jìn)去。
RequestBody requestBody = new FormBody.Builder()
.add("name", "value")
.build();
Request request = new Request.Builder().url(url).post(requestBody).build();
進(jìn)行異步請(qǐng)求
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
ResponseBody body = response.body();
if (body != null) {
Log.e(TAG, "onResponse: " + body.string());
}
}
});
到此,一些基本使用基本講完,后面會(huì)接著講一些其他場(chǎng)景的應(yīng)用。
由于水平有限,如有錯(cuò)誤,歡迎指出,相互學(xué)習(xí),共同進(jìn)步。