1. 程式人生 > >okhttp詳解(引數)

okhttp詳解(引數)

OkHttpClient client=new OkHttpClient.Builder()
    .connectTimeout(60, TimeUnit.SECONDS)       //設定連線超時
    .readTimeout(60, TimeUnit.SECONDS)          //設定讀超時
    .writeTimeout(60,TimeUnit.SECONDS)          //設定寫超時
    .retryOnConnectionFailure(true)             //是否自動重連
    .build();                                   //構建OkHttpClient物件

retryOnConnectionFailure: 
當遇到連線問題時配置此客戶端重試或者不重試

//================================
新增網路攔截器:

第一步:(預編譯)

compile 'com.squareup.okhttp3:logging-interceptor:3.5.0'

定義攔截工具:
public class HttpLogger implements HttpLoggingInterceptor.Logger {
    @Override
    public void log(String message) {
        Log.d("HttpLogInfo", message);
    }

新增攔截事件:
HttpLoggingInterceptor logInterceptor = new HttpLoggingInterceptor(new HttpLogger());
        logInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        mOkHttpClient = new OkHttpClient.Builder()
            .connectTimeout(15, TimeUnit.SECONDS)
            .addNetworkInterceptor(logInterceptor)
            .build();
     --------------------------------------------------

    addNetworkInterceptor--->http://www.jianshu.com/p/e044cab4f530
    HttpLoggingInterceptor.level.BASIC;// 記錄請求和響應行。
    HttpLoggingInterceptor.level.BODY;// 記錄請求和響應行及其各自的標題和正文(如果存在)。
    HttpLoggingInterceptor.level.HEADERS;// 記錄請求和響應行及其相應的標題
    HttpLoggingInterceptor.level.NONE;// 沒有日誌

在給OkhttpClient新增網路請求攔截器的時候需要注意,應該呼叫方法addNetworkInterceptor,而不是addInterceptor。因為有時候可能會通過cookieJar在header裡面去新增一些持久化的cookie或者session資訊。這樣就在請求頭裡面就不會打印出這些資訊。

注意:
okHttp2.7用的是new FormEncodingBuilder(),而OkHttp3.x用的是FormBody.Builder();

OkHttp MediaType的使用:

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

屬性: 
text/html : HTML格式
text/plain :純文字格式      
text/xml :  XML格式
image/gif :gif圖片格式    
image/jpeg :jpg圖片格式 
image/png:png圖片格式
以application開頭的媒體格式型別:

application/xhtml+xml :XHTML格式
application/xml     : XML資料格式
application/atom+xml  :Atom XML聚合格式    
application/json    : JSON資料格式
application/pdf       :pdf格式  
application/msword  : Word文件格式
application/octet-stream : 二進位制流資料(如常見的檔案下載)
application/x-www-form-urlencoded : <form encType=””>中預設的encType,form表單資料被編碼為key/value格式傳送到伺服器(表單預設的提交資料的格式)

另外一種常見的媒體格式是上傳檔案之時使用的:
multipart/form-data : 需要在表單中進行檔案上傳時,就需要使用該格式
注意:MediaType.parse("image/png")裡的"image/png"不知道該填什麼,可以參考---》http://www.w3school.com.cn/media/media_mimeref.asp
如何使用呢?(在請求體裡面寫入型別和需要寫入的資料,通過post請求)
String body = "hdsoifhjoihdsfh";
RequestBody body = RequestBody.create(MEDIA_TYPE_MARKDOWN, body);

下面對應okhttp,還有兩種requestBody,一個是FormBody,一個是MultipartBody

RequestBody的使用:

// 提交一個表單
RequestBody formBody = new FormBody.Builder()
        .add("gid", "2592154")
        .add("rid", "32214405")
        .build();

// 通過流的方式
RequestBody requestBody = new RequestBody() {
      // 請求的型別
      @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, factor(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);
      }

// 分塊請求
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()
        .url("https://api.github.com/repos/square/okhttp/issues")
        .header("User-Agent", "OkHttp Headers.java")
        .addHeader("Accept", "application/json; q=0.5")
        .addHeader("Accept", "application/vnd.github.v3+json")
        .build();

 以下就是一個典型的POST請求:
    POST / HTTP/1.1
    Host: www.baidu.com
    User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
    Gecko/20050225 Firefox/1.0.1
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 40
    Connection: Keep-Alive
    Accept-Language: ZH

請求的是json格式post解析:

post請求提body的新增
final JSONObject reJson = new JSONObject();
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
 RequestBody formBody = RequestBody.create(JSON, String.valueOf(reJson));

Builder裡面的引數:

final Dispatcher dispatcher;  //分發器
final Proxy proxy;  //代理
final List<Protocol> protocols; //協議
final List<ConnectionSpec> connectionSpecs; //傳輸層版本和連線協議
final List<Interceptor> interceptors; //攔截器
final List<Interceptor> networkInterceptors; //網路攔截器
final ProxySelector proxySelector; //代理選擇
final CookieJar cookieJar; //cookie
final Cache cache; //快取
final InternalCache internalCache;  //內部快取
final SocketFactory socketFactory;  //socket 工廠
final SSLSocketFactory sslSocketFactory; //安全套接層socket 工廠,用於HTTPS
final CertificateChainCleaner certificateChainCleaner; // 驗證確認響應證書 適用 HTTPS 請求連線的主機名。
final HostnameVerifier hostnameVerifier;    //  主機名字確認
final CertificatePinner certificatePinner;  //  證書鏈
final Authenticator proxyAuthenticator;     //代理身份驗證
final Authenticator authenticator;      // 本地身份驗證
final ConnectionPool connectionPool;    //連線池,複用連線
final Dns dns;  //域名
final boolean followSslRedirects;  //安全套接層重定向
final boolean followRedirects;  //本地重定向
final boolean retryOnConnectionFailure; //重試連線失敗
final int connectTimeout;    //連線超時
final int readTimeout; //read 超時
final int writeTimeout; //write 超時

如果不設定,瞭解下面的預設設定:

         dispatcher = new Dispatcher();
        protocols = DEFAULT_PROTOCOLS;
        connectionSpecs = DEFAULT_CONNECTION_SPECS;
        proxySelector = ProxySelector.getDefault();
        cookieJar = CookieJar.NO_COOKIES;
        socketFactory = SocketFactory.getDefault();
        hostnameVerifier = OkHostnameVerifier.INSTANCE;
        certificatePinner = CertificatePinner.DEFAULT;
        proxyAuthenticator = Authenticator.NONE;
        authenticator = Authenticator.NONE;
        connectionPool = new ConnectionPool();
        dns = Dns.SYSTEM;
        followSslRedirects = true;
        followRedirects = true;
        retryOnConnectionFailure = true;
        connectTimeout = 10_000;
        readTimeout = 10_000;
        writeTimeout = 10_000;