OkHttp3的基本用法

来源:互联网 发布:hdfs java api 远程 编辑:程序博客网 时间:2024/05/17 22:47

这篇文章说下OkHttp的基本用法,是最新的3哦,如果你曾经在网上搜索OkHttp怎么使用发现有些类没有了可能是因为人家说的是2。

首先说下OkHttp3是Java和Android都能用,Android还有一个著名网络库叫Volley,那个只有Android能用。

导入

自己到入jar包,别漏了okio:

okhttp-3.3.0.jarokio-1.8.0.jar

maven方式:

<dependency>  <groupId>com.squareup.okhttp3</groupId>  <artifactId>okhttp</artifactId>  <version>3.3.0</version></dependency>

gradle方式:

compile 'com.squareup.okhttp3:okhttp:3.3.0'

Get请求

String url = "https://www.baidu.com/";OkHttpClient okHttpClient = new OkHttpClient();Request request = new Request.Builder()    .url(url)    .build();Call call = okHttpClient.newCall(request);try {    Response response = call.execute();    System.out.println(response.body().string());} catch (IOException e) {    e.printStackTrace();}

如果你需要在request的的header添加参数。例如Cookie,User-Agent什么的,就是

Request request = new Request.Builder()    .url(url)    .header("键", "值")    .header("键", "值")    ...    .build();

response的body有很多种输出方法,string()只是其中之一,注意是string()不是toString()。如果是下载文件就是response.body().bytes()。
另外可以根据response.code()获取返回的状态码。

Post请求

String url = "https://www.baidu.com/";OkHttpClient okHttpClient = new OkHttpClient();RequestBody body = new FormBody.Builder()    .add("键", "值")    .add("键", "值")    ...    .build();Request request = new Request.Builder()    .url(url)    .post(body)    .build();Call call = okHttpClient.newCall(request);try {    Response response = call.execute();    System.out.println(response.body().string());} catch (IOException e) {    e.printStackTrace();}

post请求创建request和get是一样的,只是post请求需要提交一个表单,就是RequestBody。表单的格式有好多种,普通的表单是:

RequestBody body = new FormBody.Builder()    .add("键", "值")    .add("键", "值")    ...    .build();

RequestBody的数据格式都要指定Content-Type,常见的有三种:

  • application/x-www-form-urlencoded 数据是个普通表单
  • multipart/form-data 数据里有文件
  • application/json 数据是个json

但是好像以上的普通表单并没有指定Content-Type,这是因为FormBody继承了RequestBody,它已经指定了数据类型为application/x-www-form-urlencoded。

private static final MediaType CONTENT_TYPE = MediaType.parse("application/x-www-form-urlencoded");

再看看数据为其它类型的RequestBody的创建方式。

如果表单是个json:

MediaType JSON = MediaType.parse("application/json; charset=utf-8");RequestBody body = RequestBody.create(JSON, "你的json");

如果数据包含文件:

RequestBody requestBody = new MultipartBody.Builder()    .setType(MultipartBody.FORM)    .addFormDataPart("file", file.getName(), RequestBody.create(MediaType.parse("image/png"), file))    .build();

上面的MultipartBody也是继承了RequestBody,看下源码可知它适用于这五种Content-Type:

public static final MediaType MIXED = MediaType.parse("multipart/mixed");public static final MediaType ALTERNATIVE = MediaType.parse("multipart/alternative");public static final MediaType DIGEST = MediaType.parse("multipart/digest");public static final MediaType PARALLEL = MediaType.parse("multipart/parallel");public static final MediaType FORM = MediaType.parse("multipart/form-data");

另外如果你上传一个文件不是一张图片,但是MediaType.parse(“image/png”)里的”image/png”不知道该填什么,可以参考下这个页面。

同步与异步

从上文已经能知道call.execute()就是在执行http请求了,但是这是个同步操作,是在主线程运行的。如果你在android的UI线程直接执行这句话就出异常了。
OkHttp也帮我们实现了异步,写法是:

String url = "https://www.baidu.com/";OkHttpClient okHttpClient = new OkHttpClient();Request request = new Request.Builder()        .url(url)        .build();Call call = okHttpClient.newCall(request);call.enqueue(new Callback() {    @Override    public void onFailure(Call call, IOException e) {        e.printStackTrace();    }    @Override    public void onResponse(Call call, Response response) throws IOException {        System.out.println("我是异步线程,线程Id为:" + Thread.currentThread().getId());    }});for (int i = 0; i < 10; i++) {    System.out.println("我是主线程,线程Id为:" + Thread.currentThread().getId());    try {        Thread.currentThread().sleep(100);    } catch (InterruptedException e) {        e.printStackTrace();    }}

执行结果是:

我是主线程,线程Id:1我是主线程,线程Id:1我是主线程,线程Id:1我是异步线程,线程Id:11我是主线程,线程Id:1我是主线程,线程Id:1我是主线程,线程Id:1我是主线程,线程Id:1我是主线程,线程Id:1我是主线程,线程Id:1我是主线程,线程Id:1

显然onFailure()和onResponse()分别是在请求失败和成功时会调用的方法。这里有个要注意的地方,onFailure()和onResponse()是在异步线程里执行的,所以如果你在Android把更新UI的操作写在这两个方法里面是会报错的,这个时候可以用runOnUiThread这个方法。

自动管理Cookie

Request经常都要携带Cookie,上面说过request创建时可以通过header设置参数,Cookie也是参数之一。就像下面这样:

Request request = new Request.Builder()    .url(url)    .header("Cookie", "xxx")    .build();

然后可以从返回的response里得到新的Cookie,你可能得想办法把Cookie保存起来。
但是OkHttp可以不用我们管理Cookie,自动携带,保存和更新Cookie。
方法是在创建OkHttpClient设置管理Cookie的CookieJar:

private final HashMap<String, List<Cookie>> cookieStore = new HashMap<>();OkHttpClient okHttpClient = new OkHttpClient.Builder()    .cookieJar(new CookieJar() {        @Override        public void saveFromResponse(HttpUrl httpUrl, List<Cookie> list) {            cookieStore.put(httpUrl.host(), list);        }        @Override        public List<Cookie> loadForRequest(HttpUrl httpUrl) {            List<Cookie> cookies = cookieStore.get(httpUrl.host());            return cookies != null ? cookies : new ArrayList<Cookie>();        }    })    .build();

这样以后发送Request都不用管Cookie这个参数也不用去response获取新Cookie什么的了。还能通过cookieStore获取当前保存的Cookie。
最后,new OkHttpClient()只是一种快速创建OkHttpClient的方式,更标准的是使用OkHttpClient.Builder()。后者可以设置一堆参数,例如超时时间什么的。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 吃了变绿的土豆怎么办 吃炸洋芋中毒了怎么办 脸上长毒气痘痘怎么办 吃鸡游戏中遇到毒气怎么办 吃多了颠茄片怎么办 玲珑骰子沾了水怎么办 花的枝干长歪了怎么办 电脑中毒了怎么办开不了机 台湾竹长得太高怎么办 文竹长得太高怎么办 桑叶牡l丹长虫怎么办 日本海棠开完花后枯萎了怎么办 长寿冠海棠烂根怎么办 夏季长寿冠海棠掉叶怎么办 竹节海棠有点烂根怎么办? 丽格海棠烂茎怎么办 长寿花徒长不开花怎么办 长寿花植株长了怎么办 丽格海棠不爱长怎么办 竹节海棠太高了怎么办 绿萝叶子发黄烂根怎么办 发财树叶子发黄烂根怎么办 君子兰烂根叶子发黄怎么办 四季海棠花叶子干了怎么办 海棠花叶子枯萎枝干发黑怎么办 长寿花叶尖焦了怎么办 新买的盆栽蔫了怎么办 熬中药水太多了怎么办 秋根海棠烂根怎么办 大叶海棠烂根怎么办 玻璃海棠长得很高怎么办 玫瑰海棠叶子干焦怎么办 海棠树树干生虫怎么办 天竺葵花骨朵有虫子了怎么办? 被刺梅的刺扎了怎么办 被刺梅的刺划手了怎么办 虎刺花叶子黄了怎么办 地栽月季叶子发黄怎么办 梅花浇水浇多了怎么办 深水井底下花管进水量小怎么办 盆景对节白腊树叶尖干枯怎么办