在做處理網(wǎng)絡(luò)請求的時候,可以直觀的看到每次請求的傳參和響應(yīng)是非常有幫助的。
public static API get() {
if (api == null) {
synchronized (Retrofit.class) {
if (api == null) {
OkHttpClient httpClient = new OkHttpClient
.Builder()
.addInterceptor(new RequestLoggerInterceptor())
.addInterceptor(new ResponseLogInterCeptor())
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API.BASE_URL)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient)
.build();
api = retrofit.create(API.class);
}
}
}
return api;
}
請求的攔截器非常簡單
static class RequestLoggerInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Log.d(TAG, "url = : " + request.url());
Log.d(TAG, "method = : " + request.method());
Log.d(TAG, "headers = : " + request.headers());
Log.d(TAG, "body = : " + request.body());
return chain.proceed(request);
}
}
而響應(yīng)的攔截器需要考慮body()
只能被調(diào)用一次的問題,開始的時候我單純的以為這樣就可以
static class responseLogInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
Log.d(TAG, "code = : " + response.code());
Log.d(TAG, "message = : " + response.message());
Log.d(TAG, "protocol = : " + response.protocol());
Log.d(TAG, "string = : " + response.body().string());
Response clone = response.newBuilder().build();
return clone;
}
}
開始以為這樣就是clone
了一個Response
對象方仿,后來發(fā)現(xiàn)太年輕了
public Builder newBuilder() {
return new Builder(this);
}
Builder(Response response) {
this.request = response.request;
this.protocol = response.protocol;
this.code = response.code;
this.message = response.message;
this.handshake = response.handshake;
this.headers = response.headers.newBuilder();
this.body = response.body;
this.networkResponse = response.networkResponse;
this.cacheResponse = response.cacheResponse;
this.priorResponse = response.priorResponse;
this.sentRequestAtMillis = response.sentRequestAtMillis;
this.receivedResponseAtMillis = response.receivedResponseAtMillis;
}
public Response build() {
if (request == null) throw new IllegalStateException("request == null");
if (protocol == null) throw new IllegalStateException("protocol == null");
if (code < 0) throw new IllegalStateException("code < 0: " + code);
if (message == null) throw new IllegalStateException("message == null");
return new Response(this);
}
同一個body
嘛。
稍微改一下
static class ResponseLogInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
Log.d(TAG, "code = : " + response.code());
Log.d(TAG, "message = : " + response.message());
Log.d(TAG, "protocol = : " + response.protocol());
if (response.body() != null && response.body().contentType() != null) {
MediaType mediaType = response.body().contentType();
String string = response.body().string();
Log.d(TAG, "mediaType = : " + mediaType.toString());
Log.d(TAG, "string = : " + string);
ResponseBody responseBody = ResponseBody.create(mediaType, string);
return response.newBuilder().body(responseBody).build();
} else {
return response;
}
}
}
關(guān)鍵在于response.newBuilder().body(responseBody).build();
這里傳入了一個新構(gòu)建的body
。這樣才能保證在后續(xù)操作中調(diào)用body.string()
不會拋出異常。
當(dāng)然在輸入body().string()
的時候艳吠,還要做MediaType
的類型判斷