Android学习笔记(十九) OkHttp
一、概述
根据我的理解,OkHttp是为了方便访问网络或者获取服务器的资源,而封装出来的一个工具包。通常的使用步骤是:首先初始化一个OkHttpClient对象,然后使用builder模式构造一个Request,之后使用Call来执行这个Request。其中,OkHttpClient一般只使用一个,而OkHttpClient的newCall方法则对应每次请求的执行。
二、Get
2.1 步骤分解
- 拿到OkHttpClient对象
- 构造Request
- 将Request封装为Call
- 执行Call(直接execute或者enqueue)
2.2 程序
public void doGet(View view) throws IOException{
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url("http://www.imooc.com/").build();
Call call = client.newCall(request);
call.enqueue(new Callback(){
@Override
public void onFailure(Call call, IOException e) {
Log.e("okHttp",e.getMessage());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.d("okHttp","doGet success!");
String string = response.body().string();
Log.d("okHttp Content",string);
}
});
}
上面的enqueue也可以换成execute,不过执行后返回一个Response对象。
相应代码替换成:
Response response = call.execute();
if(response.isSuccessful){
return response.body().string();
}else{
throw new IOException("Unexpected code " + response);
}
三、Post键值对
3.1 步骤分解
- 拿到OkHttpClient对象
- 构造RequestBody
- 构造Request
- 将Request封装为Call
- 执行Call
3.2 代码
public void doPost(View view){
OkHttpClient client = new OkHttpClient();
RequestBody body = new FormBody.Builder().builder()
.add("username","admin")
.add("password","123")
.build();
Request.Builder builder = new Request.Builder();
Request = builder.url(mBaseUrl+"login").post(body).build();
Call call = client.newCall(request);
call.enqueue(new Callback(){
@Override
public void onFailure(Call call, IOException e) {
Log.e("okHttp",e.getMessage());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.d("okHttp","doGet success!");
String string = response.body().string();
Log.d("okHttp Content",string);
}
});
}
Call那个步骤在多数程序中都会用到,所以最好是抽取成为一个函数。在服务器端使用的是struts2架构,因此需要添加一个action,在所需调用的函数中将username和password打印出来就能看到post上去的数据了。
四、Post JSON(字符串)
和上面的步骤唯一不同的是RequestBody的构造。这里使用的是RequestBody的静态方法create()。
RequestBody body = RequestBody.create(MediaType.parse("text/plain;charset=utf-8"),"{username:admin,password:123}");
在服务器端的函数代码为:
public String postString(){
HttpServletRequest request = ServletActionContext.getRequest();
ServletInputStream is = request.getInputStream();
StringBuilder sb = new StringBuilder();
int len = 0;
byte[] buf = new byte[1024];
while((len = is.read(buf)) != -1){
sb.append(new String(buf, 0, len));
}
System.out.println(sb.toString());
return null;
}
五、Post File
参考上面的代码,这里构造RequestBody也是调用它的静态方法create(),只不过参数改成了跟File相适应的。
重复代码已省去。至于MediaType参数,参考http://www.w3school.com.cn/media/media_mimeref.asp。
File file = new File(Environment.getExternalStorageDirectory(),"test.jpg");
if(!file.exists()){
Log.e("file error","not exist!");
return;
}
RequestBody body = RequestBody.create(MediaType.parse("application/octet-stream"),file);
服务器端的程序也和上面的程序大同小异,只不过改成用FileOutputStream来接受InputStream里面的数据,而不是上面的StringBuilder。
public String postFile(){
HttpServletRequest request = ServletActionContext.getRequest();
ServletInputStream is = request.getInputStream();
String dir
= ServletActionContext.getServletContext().getRealPath("files"
);
File file = new File(dir,"test.jpg");
FileOutputStream fos = new FileOutputStream(file);
int len = 0;
byte[] buf = new byte[1024]; while((len = is.read(buf)) != -1){
fos.write(buf, 0, len);
} fos.flush();
fos.close(); return null;
}
这里有个需要注意的地方,getRealPath得到的路径默认是tomcat下webapps中的项目文件夹下。因为每次重启服务器里面的文件都会被删除,所以我更改了路径:
<Context path="/VCloud" docBase="D:\Workspace\VCloudDir" debug="0" reloadable="true"/>
我把文件test.jpg放在D:\Workspace\VCloudDir\files下,然后在浏览器中输入localhost:8080/VCloud/files/test.jpg就能打开这个文件。
六、上传文件以及参数
使用MultipartBody的意义在于:传输文件的同时可以传输字段;可以指定文件名;可以一次上传多个文件。
代码仅展示RequestBody部分,其他部分和上面基本一致。
File file = new File(Environment.getExternalStorageDirectory(),"test.jpg");
RequestBody fileRequestBody = RequestBody.create(MediaType.parse("application/octet-stream"),file);
MultipartBody.Builder multipartBuilder = new MultipartBody.Builder();
RequestBody body = multipartBuilder
.type(MultipartBody.FORM)
.addFormDataPart("username","admin")
.addFormDataPart("password","123")
.addFormDataPart("mPhoto","test.jpg",fileRequestBody)
.build();
服务端部分:
public File mPhoto;
public String mPhotoFileName;//注意写法是固定的
public String uploadInfo(){ if(mPhoto == null){
System.out.println(mPhotoFileName + " is null .);
} String dir = ServletActionContext.getServletContext().getRealPath("files"); File file = new File(dir, mPhotoFileName);
FileUtils.copyFile(mPhoto, file); return null;
}
七、下载文件
和get方法类似,不同之处在于对得到的Response的处理,即onResponse里面的内容。
url就是文件地址,如localhost:8080/VCloud/files/test.jpg。
public void onResponse(Response response){
Log.d("onResponse","onResponse");
InputStream is = response.body().byteStream();
int len = 0;
File file = new File(Environment.getExternalStorageDirectory(),"test.jpg");
byte[] buf = new byte[128];
FileOutputStream fos = new FileOutputStream(file);
while((len = is.read(buf)) != -1){
fos.write(buf, 0, len);
}
fos.flush();
fos.close();
is.close();
Log.d("download","download success!");
}
Android学习笔记(十九) OkHttp的更多相关文章
- python3.4学习笔记(十九) 同一台机器同时安装 python2.7 和 python3.4的解决方法
python3.4学习笔记(十九) 同一台机器同时安装 python2.7 和 python3.4的解决方法 同一台机器同时安装 python2.7 和 python3.4不会冲突.安装在不同目录,然 ...
- 【转】Pro Android学习笔记(九八):BroadcastReceiver(2):接收器触发通知
文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.sina.com.cn/flowingflying或作者@恺风Wei-傻瓜与非傻瓜 广播接 ...
- 【转】 Pro Android学习笔记(九二):AsyncTask(1):AsyncTask类
文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowingflying/ 在Handler的学习系列中,学习了如何h ...
- Android学习笔记(九)——布局和控件的自定义
//此系列博文是<第一行Android代码>的学习笔记,如有错漏,欢迎指正! View是 Android中一种最基本的 UI组件,它可以在屏幕上绘制一块矩形区域,并能响应这块区域的各种事件 ...
- (C/C++学习笔记) 十九. 模板
十九. 模板 ● 模板的基本概念 模板(template) 函数模板:可以用来创建一个通用功能的函数,以支持多种不同形参,进一步简化重载函数的函数体设计. 语法: template <<模 ...
- 【转】 Pro Android学习笔记(九四):AsyncTask(3):ProgressDialog
文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowingflying/ Progress Dialog小例子 我们 ...
- 【转】 Pro Android学习笔记(九三):AsyncTask(2):小例子
目录(?)[-] 继承AsyncTask UI操作接口 使用AsyncTask 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn. ...
- Android学习笔记(九) 视图的应用布局效果
最近少了写博客,可能最近忙吧,工作上忙,因为工作原因也忙于学习,也没记录什么了,也没有按照之前的计划去学习了.现在就记录一下最近学到的. 要做Android应用,界面设计少不了,可惜之前一直在用Win ...
- 【转】 Pro Android学习笔记(九一):了解Handler(5):组件生命
文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowingflying/ 对于activity,消息是在OnCrea ...
- 【转】Pro Android学习笔记(九):了解Content Provider(下下)
Content provider作为信息的读出,比较常见的还有文件的读写,最基础的就是二进制文件的的读写,例如img文件,音频文件的读写.在数据库中存放了该文件的路径,我们可以通过ContentPro ...
随机推荐
- HDU2089 不要62 —— 数位DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2089 不要62 Time Limit: 1000/1000 MS (Java/Others) M ...
- javascript中的_return_false和return_true
1. [代码][JavaScript特效]代码 关于javascript中的 return false和return true 2008年12月22日 星期一 下午 09:31return 是 ...
- Python小练习_数据库表数据导出到excel
需求:只要传入一个表名,就能把所有的数据导入出来,字段名是excel的表头 1.要动态获取到标的字段 cur.descrption能获取到表的字段 fileds = [filed[0] for fil ...
- HDU - 1875 畅通工程再续(最小生成树)
d.c个小岛,通过建立桥,使其全部可达.求所有的桥的最小长度和. s.最小生成树,数据改成double就行了 c.Prim算法:cost[a][b]和cost[b][a]都得赋值. /* Prim算法 ...
- C++中volatile及编译器优化
首先看一下单词"volatile"的释义: volatile [ˈvɑlətl] adj. 易变的,不稳定的; (液体或油)易挥发的; 爆炸性的; 快活的,轻快的; 下边是&qu ...
- apache 安装及配置
近期想用apache运行网站,在网上查询windows 版本的中文说明文档有特别少,所以将学习到的在这里做个笔记,以便日后学习以及大家相互交流. 相关文档:http://httpd.apache.or ...
- 理解iOS Event Handling
写在前面 最近的一个iOS App项目中遇到了这么问题:通过App访问服务器的大多数资源不需要登录,但是访问某些资源是需要用户提供验证的,一般来说,通常App的做法(譬如美团App)将这些资源放在“我 ...
- 【前端】CentOS 7 系列教程之五: 安装最新版 nginx 并转发 node 服务
转载请注明出处:http://www.cnblogs.com/shamoyuu/p/linux_5.html 进入/usr/local目录 cd /usr/local 下载最新版的ngxin压缩包 w ...
- 021--python装饰器
一.装饰器含义 装饰器本质就是函数,为其它函数添加附加功能 二.装饰器原则 1.不修改被修饰函数的代码 2.不修改被修饰函数的调用方式 三.装饰器知识 装饰器 = 高阶函数 + 函数嵌套 + 闭包 四 ...
- linux中vfork对打开文件的处理
vfork和fork fork()函数是拷贝一个父进程的副本,拥有独立的代码段 数据段 堆栈空间 然而vfork是共享父亲进程的代码以及代码段 vfork是可以根据需要复制父进程空间,这样很大程度的提 ...