OkHttp 3.4入門


OkHttp 3.4入門

配置方法

(一)導入Jar包
http://repo1.maven.org/maven2/com/squareup/okhttp3/okhttp/3.4.0-RC1/okhttp-3.4.0-RC1.jar

(二)Gradle

compile 'com.squareup.okhttp3:okhttp:3.4.0-RC1'

使用方法
HTTP GET
private void get_String(){
    Request request = new Request.Builder()
            .url("http://publicobject.com/helloworld.txt")
            .build();
    new OkHttpClient().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())
                throw new IOException("Unexpected code " + response);
            Headers responseHeaders = response.headers();
            for (int i = 0, size = responseHeaders.size(); i < size; i++) {
                System.out.println(responseHeaders.name(i) + ": "
                        + responseHeaders.value(i));            }
            System.out.println(response.body().string());
        }
    });
}

 

HTTP POST

     POST json數據 
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); OkHttpClient client = new OkHttpClient();

String post(String url, String json) throws IOException {     RequestBody body = RequestBody.create(JSON, json);     Request request = new Request.Builder()       .url(url)       .post(body)       .build();     Response response = client.newCall(request).execute();     f (response.isSuccessful()) {         return response.body().string();     } else {         throw new IOException("Unexpected code " + response);     } }

POST提交鍵值對 
OkHttpClient client = new OkHttpClient();

String post(String url, String json) throws IOException {     RequestBody formBody = new FormEncodingBuilder()
    //.add("platform""android")     //.add("name""bug")     //.add("subject""XXXXXXXXXXXXXXX")
     .add("search""Jurassic Park")

    .build();       Request request = new Request.Builder()       .url("https://en.wikipedia.org/w/index.php")       .post(formBody)       .build();       Response response = client.newCall(request).execute();     if (response.isSuccessful()) {         return response.body().string();     } else {         throw new IOException("Unexpected code " + response);     } }

Headers(提取響應頭)

 

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")

.addHeader("Cookie""cookie")
        .build();
try {
    Response response = mClient.newCall(request).execute();
    if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
   /* System.out.println("Server: " + response.header("Server"));
    System.out.println("Date: " + response.header("Date"));
    System.out.println("Vary: " + response.headers("Vary"));*/
    Log.i("WY""數據:" + response.toString());
catch (IOException e) {
    e.printStackTrace();
}

 

Get請求Gson數據

static class Gist {
    Map<String, GistFile> files;
}
static class GistFile {
    String content;
}
public void run_JSON() throws Exception {
    Request request = new Request.Builder()
            .url("https://api.github.com/gists/c2a7c39532239ff261be")
            .build();
    new OkHttpClient().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()) throw new IOException("Unexpected code " + response);
            Gist gist = gson.fromJson(response.body().charStream(), Gist.class);
            for (Map.Entry<String, GistFile> entry : gist.files.entrySet()) {
                System.out.println("111 "+entry.getKey());
                System.out.println(entry.getValue().content);
            }
        }
    });
}

 

獨立請求設置
由於在一個程序中只能聲明一個OkHttpClient實例,如果要更改連接超時時間,或者其他參數可使用newBuilder進行設置。
public class PreRequestClass {
    private final OkHttpClient client new OkHttpClient();
    public void run() throws Exception {
        Request request = new Request.Builder()
                .url("http://httpbin.org/delay/1"// This URL is served with a 1 second delay.
                .build();
        // Copy to customize OkHttp for this request.
        OkHttpClient copy = client.newBuilder()
                .readTimeout(5000, TimeUnit.MILLISECONDS)
                .build();
        copy.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                System.out.println("Response 1 succeeded: " + response);
            }
        });
        OkHttpClient copy2 = client.newBuilder()
                .readTimeout(3000, TimeUnit.MILLISECONDS)
                .build();
        copy2.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                System.out.println("Response 2 succeeded: " + response);
            }
        });
    }
}

(Post方式提交String)

使用HTTP POST提交請求到服務。這個例子提交了一個markdown文檔到web服務,以HTML方式渲染markdown。因為整個請求體都在內存中,因此避免使用此api提交大文檔(大於1MB)。

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

  private final OkHttpClient client = new OkHttpClient();    

 public void run() throws Exception {  

   String postBody = ""         + "Releases\n"         + "--------\n"         + "\n"       

      " * _1.0_ May 6, 2013\n"      

       " * _1.1_ June 15, 2013\n"        

                                         " * _1.2_ August 11, 2013\n";    

   Request request = new Request.Builder()  

       .url("https://api.github.com/markdown/raw")  

       .post(RequestBody.create(MEDIA_TYPE_MARKDOWN, postBody))

        .build();  

    Response response = client.newCall(request).execute();  

   if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);  

    System.out.println(response.body().string());  

 }

Post Streaming(Post方式提交流)

以流的方式POST提交請求體。請求體的內容由流寫入產生。這個例子是流直接寫入OkioBufferedSink。你的程序可能會使用OutputStream,你可以使用BufferedSink.outputStream()來獲取。.

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

 private final OkHttpClient client = new OkHttpClient();    

 public void run() throws Exception {

    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);   

    }     };

      Request request = new Request.Builder()

        .url("https://api.github.com/markdown/raw")

        .post(requestBody)

        .build();  

    Response response = client.newCall(request).execute();

    if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

      System.out.println(response.body().string());  

 }

Posting a File(Post方式提交文件)

以文件作為請求體是十分簡單的。

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

  private final OkHttpClient client = new OkHttpClient();  

 public void run() throws Exception {

    File file = new File("README.md");

    Request request = new Request.Builder()

        .url("https://api.github.com/markdown/raw")  

       .post(RequestBody.create(MEDIA_TYPE_MARKDOWN, file))

        .build();

      Response response = client.newCall(request).execute();  

   if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

      System.out.println(response.body().string());

  }

Posting a multipart request(Post方式提交分塊請求)

MultipartBuilder可以構建復雜的請求體,與HTML文件上傳形式兼容。多塊請求體中每塊請求都是一個請求體,可以定義自己的請求 頭。這些請求頭可以用來描述這塊請求,例如他的Content-Disposition。如果Content-LengthContent-Type可 用的話,他們會被自動添加到請求頭中。

private static final String IMGUR_CLIENT_ID = "...";  

 private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");

  private final OkHttpClient client = new OkHttpClient();  

 public void run() throws Exception {     // Use the imgur image upload API as documented at https://api.imgur.com/endpoints/image

    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()

        .header("Authorization""Client-ID " + IMGUR_CLIENT_ID)

        .url("https://api.imgur.com/3/image")

        .post(requestBody)

        .build();

      Response response = client.newCall(request).execute();

    if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);  

   System.out.println(response.body().string());  

 }

Response Caching(響應緩存)

為了緩存響應,你需要一個你可以讀寫的緩存目錄,和緩存大小的限制。這個緩存目錄應該是私有的,不信任的程序應不能讀取緩存內容。
一個緩存目錄同時擁有多個緩存訪問是錯誤的。大多數程序只需要調用一次new OkHttp(),在第一次調用時配置好緩存,然后其他地方只需要調用這個實例就可以了。否則兩個緩存示例互相干擾,破壞響應緩存,而且有可能會導致程序崩潰。
響應緩存使用HTTP頭作為配置。你可以在請求頭中添加Cache-Control: max-stale=3600 ,OkHttp緩存會支持。你的服務通過響應頭確定響應緩存多長時間,例如使用Cache-Control: max-age=9600

private final OkHttpClient client;  

 public CacheResponse(File cacheDirectory) throws Exception {

    int cacheSize = 10 * 1024 * 1024; // 10 MiB  

   Cache cache = new Cache(cacheDirectory, cacheSize);  

    client = new OkHttpClient.Builder()

        .cache(cache)

        .build();  

 }

    public void run() throws Exception {   

  Request request = new Request.Builder()

        .url("http://publicobject.com/helloworld.txt")

        .build();

      Response response1 = client.newCall(request).execute();  

   if (!response1.isSuccessful()) throw new IOException("Unexpected code " + response1);

      String response1Body = response1.body().string();

    System.out.println("Response 1 response:          " + response1);  

   System.out.println("Response 1 cache response:    " + response1.cacheResponse());

    System.out.println("Response 1 network response:  " + response1.networkResponse());  


    Response response2 = client.newCall(request).execute();


    if (!response2.isSuccessful()) throw new IOException("Unexpected code " + response2);  

    String response2Body = response2.body().string();  

   System.out.println("Response 2 response:          " + response2);

    System.out.println("Response 2 cache response:    " + response2.cacheResponse());  

   System.out.println("Response 2 network response:  " + response2.networkResponse());  

    System.out.println("Response 2 equals Response 1? " + response1Body.equals(response2Body));

  }

為了防止使用緩存的響應,可以用CacheControl.FORCE_NETWORK。為了防止它使用網絡,使用 CacheControl.FORCE_CACHE。需要注意的是:如果您使用FORCE_CACHE和網絡的響應需求,OkHttp則會返回一個504 提示,告訴你不可滿足請求響應。

Handling authentication(處理驗證)

OkHttp會自動重試未驗證的請求。當響應是401 Not Authorized時,Authenticator會被要求提供證書。Authenticator的實現中需要建立一個新的包含證書的請求。如果沒有證書可用,返回null來跳過嘗試。

 private final OkHttpClient client;  

  public Authenticate() {

    client = new OkHttpClient.Builder()

        .authenticator(new Authenticator() {

          @Override

 public Request authenticate(Route route, Response response) throws IOException {  

           System.out.println("Authenticating for response: " + response);  

           System.out.println("Challenges: " + response.challenges());

            String credential = Credentials.basic("jesse""password1");

            return response.request().newBuilder()

                .header("Authorization", credential)

                .build();

          }  

       }).build();

  }  

  public void run() throws Exception {

    Request request = new Request.Builder()  

       .url("http://publicobject.com/secrets/hellosecret.txt")

        .build();

      Response response = client.newCall(request).execute();

    if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);  

    System.out.println(response.body().string());  

 }

 


 不用header添加參數,formbody添加方法:

可以遍歷formBody,循環添加 formBody

最好的辦法是重寫 FormBody,追加添加參數的方法。

  private void intercep() {

    OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(new Interceptor() {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request original = chain.request();
//請求定制:添加請求
Request.Builder requestBuilder = original.newBuilder()
.header("APIKEY", "API_KEY");
//請求體定制:統一添加token參數
if (original.body() instanceof FormBody) {
FormBody.Builder newFormBody = new FormBody.Builder();
FormBody oidFormBody = (FormBody) original.body();
for (int i = 0; i < oidFormBody.size(); i++) {
newFormBody.addEncoded(oidFormBody.encodedName(i), oidFormBody.encodedValue(i));
}
newFormBody.add("token", "API_TOKEN");
requestBuilder.method(original.method(), newFormBody.build());
}
Request request = requestBuilder.build();
return chain.proceed(request);
}
});
}

OkHttp官方文檔:https://github.com/square/okhttp/wiki

 

源碼下載

 

 






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM