zoukankan      html  css  js  c++  java
  • 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 "        + "-------- "        + " "      

          " * _1.0_ May 6, 2013 "     

           " * _1.1_ June 15, 2013 "       

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

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

           sink.writeUtf8("------- "); 

           for (int i = 2; i <= 997; i++) {

              sink.writeUtf8(String.format(" * %s = %s ", 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

     

    源码下载

     

     





  • 相关阅读:
    疯子在思考之-异常与return 的差别
    MANIFEST.MF 文件内容完全详解
    疯子奉献-一个符号惹的祸
    疯子在思考之-从日志想到的软件架构
    疯子在思考之java 线程的那点事儿
    linux 自动重启tomcat 脚本
    tomcat 优化及错误All threads (10) are currently busy, waiting. Increase maxThreads错误
    log4j继承
    substring 陷阱
    每天一个随笔
  • 原文地址:https://www.cnblogs.com/ut2016-progam/p/5673127.html
Copyright © 2011-2022 走看看