okHttp使用
本文转载自:http://www.cnblogs.com/qifengshi/p/5405550.html
okHttp是一个http请求框架,相当于android原生的httpclient和httpURLConnectiond的封装,让写法更加简单,可以处理更加复杂的网络请求;
OkHttp使用:
Gradle导入:
compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'com.squareup.okio:okio:1.6.0'
或者用meven导入;
使用get请求:get分为get同步请求和get异步请求:
首先定义一个okhttpclient和Requeset:
private OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().
url("http://www.baidu.com").
build();
也可以在创建Requeset的时候就传入参数:
Request request = new Request.Builder().
url("http://www.baidu.com").
addHeader("User-Agent","android").
header("Content-Type","text/html; charset=utf-8").
build();
通过addHeader和header方法为请求增加请求头部,注意使用header(name, value)可以设置唯一的name、value。如果已经有值,旧的将被移除,然后添加新的。使用addHeader(name, value)可以添加多值(添加,不移除已有的)。
同步的get方法,通过client.newCall(request).execute()方法得到请求的response.
Response response = okHttpClient.newCall(request).execute();
OkHttp封装了很多处理response的方法,比如response.headers()的得到headers
Headers headers = response.headers();
for (int i = 0; i < headers.size(); i++) {
System.out.println(headers.name(i) + ": " + headers.value(i)); }
就得到请求头的内容:
Date: Mon, 18 Apr 2016 05:23:43 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: Keep-Alive
Vary: Accept-Encoding
Set-Cookie: BAIDUID=A323EC9BF678C0EB78E20741FD71211B:FG=1; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: BIDUPSID=A323EC9BF678C0EB78E20741FD71211B; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: PSTM=1460957023; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: BDSVRTM=0; path=/
Set-Cookie: BD_HOME=0; path=/
Set-Cookie: H_PS_PSSID=1434_19672_18281_19690_17948_18205_19558_15952_12257; path=/; domain=.baidu.com
P3P: CP=" OTI DSP COR IVA OUR IND COM "
Cache-Control: private
Cxy_all: baidu+2db7793e0e32b9f6c20be8f623e1ae43
Expires: Mon, 18 Apr 2016 05:22:55 GMT
X-Powered-By: HPHP
Server: BWS/1.1
X-UA-Compatible: IE=Edge,chrome=1
BDPAGETYPE: 1
BDQID: 0xfacc6fc10004ca96
BDUSERID: 0
OkHttp-Sent-Millis: 1460957021226
OkHttp-Received-Millis: 1460957021430
响应报文的实体可以通过response.body().string()获取;如果希望获得返回的二进制字节数组,则调用response.body().bytes();如果你想拿到返回的inputStream,则调用response.body().byteStream()。
异步的get请求得到的response方法是通过如下方法:
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});
在onResponse方法中,执行请求成功的代码,onFailure方法中,执行请求失败的代码
下面给一个完整的异步get的栗子
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.text.method.ScrollingMovementMethod;
import android.widget.TextView; import java.io.IOException; import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Headers;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response; public class MainActivity extends AppCompatActivity { private OkHttpClient okHttpClient = new OkHttpClient();
public TextView show;
public Handler handler = new Handler(); @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
show = (TextView) findViewById(R.id.show);
show.setMovementMethod(ScrollingMovementMethod.getInstance());
Request request = new Request.Builder().
url("http://www.baidu.com").
addHeader("User-Agent", "android").
header("Content-Type", "text/html; charset=utf-8").
get().
build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) { }
@Override
public void onResponse(Call call, final Response response) throws IOException {
final Headers headers = response.headers();
final String str = response.body().string();
handler.post(new Runnable() {
@Override
public void run() {
for (int i = 0; i < headers.size(); i++) {
show.append(headers.name(i) + ": " + headers.value(i));
show.append(str);
}
}
}); }
}); } }
其实按照官网说的,回调是发生在response 的headers准备好就发生的,所以有时候请求response的实体部分会发生阻塞。
post请求——键值对为参数。
post请求和get请求除了在构建request上面不同以外,在处理response上面都是一样的,所以下面我们只讨论一下post构建request,当然post也是支持同步post和异步post的,可以参考get方法。
在构建post的request时候,首先用FormBody.Builder去构建request的body部分,栗子如下,当然这是OKHttp3的方法.
FormBody.Builder builder = new FormBody.Builder();
for(int i = 0 ; i < key.size() ;i ++){
builder.add(key.get(i),value.get(i));
}
RequestBody body = builder.build();
builder中add的是要加入的参数键值对。得到要构造的body后用
Request request = new Request.Builder().url(url).post(body).build();
获得请求的request,后面的操作就和get方法是一样的,这里可以参考异步get的栗子,构建一个post的request.下面的写法原封不变。
post请求--多种类型的body
上文已经说了post和get的用法主要在构建不同的request上面,所以接下来我们主要讨论的也是如何构建request.
参考上面,我们首先要创建一个requestBody,我们可以用下面的方式去构建,当然这也是okhttp3的方法
MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
已表单上传的形式去提交post。我们看一下builder的方法
/** Add a part to the body. */
public Builder addPart(RequestBody body) {
return addPart(Part.create(body));
} /** Add a part to the body. */
public Builder addPart(Headers headers, RequestBody body) {
return addPart(Part.create(headers, body));
} /** Add a form data part to the body. */
public Builder addFormDataPart(String name, String value) {
return addPart(Part.createFormData(name, value));
} /** Add a form data part to the body. */
public Builder addFormDataPart(String name, String filename, RequestBody body) {
return addPart(Part.createFormData(name, filename, body));
}
从这里我们可以看出可以直接用 public Builder addFormDataPart(String name, String filename, RequestBody body)
上传一个File,最后一个参数是请求的实体,可以通过 RequestBody.create(final MediaType contentType, final File file)
获得,而MediaType
则可以通过下面方法获得
//调用judgeType方法
private static final MediaType MEDIA_TYPE = MediaType.parse(judgeType(fileName);
//judge方法如下
private String judgeType(String path) {
FileNameMap fileNameMap = URLConnection.getFileNameMap();
String contentTypeFor = fileNameMap.getContentTypeFor(path);
if (contentTypeFor == null) {
contentTypeFor = "application/octet-stream";
}
return contentTypeFor;
}
由于我后台能力比较渣,这里用一个官网的例子来实现一遍我刚才讨论的方法。
MultipartBody.Builder builder = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("image", "logo-square.png",
RequestBody.create(MEDIA_TYPE_PNG, new File("website/static/logo-square.png")));
RequestBody requestBody = builder.build(); Request request = new Request.Builder()
.header("Authorization", "Client-ID " +"9199fdef135c122")
.url("https://api.imgur.com/3/image")
.post(requestBody)
.build();
当然除了这个方法以外,调用如下方法也是可以的,我们可以利用name和filename自己构造Header传上去。
public Builder addPart(Headers headers, RequestBody body) {
return addPart(Part.create(headers, body))
栗子如下:
builder.addPart(Headers.of("Content-Disposition", "form-data; name=\"" + name + "\"; filename=\"" + fileName + "\""),fileBody);
后面的写法和上面类似,这样我们就实现了文件上传的写法。
文件下载
刚才我们上面已经说了,希望获得返回的二进制字节数组,则调用response.body().bytes();如果你想拿到返回的inputStream,则调用response.body().byteStream()。换句话说,文件的下载可以简单的通过get请求,得到相应的response,在把他的实体转换成二进制流写入文件,就是实现了文件的下载。主要的写法就是文件的读写,跟OKHttp关系不大,当然我们也可以用okio来实现文件的读写,这里水平有限就不介绍了。下面给一个简单的例子。
private void _download(final String url, final String destFileDir, final ResultCallback callback) {
final Request request = new Request.Builder().url(url).build();
final Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) { } @Override
public void onResponse(Call call, Response response) throws IOException {
InputStream is = null;
byte[] buf = new byte[2048];
int len = 0;
FileOutputStream fos = null;
try {
is = response.body().byteStream();
File file = new File(destFileDir, getFileName(url));
fos = new FileOutputStream(file);
while((len = is.read(buf)) != -1){
fos.write(buf,0,len);
}
fos.flush();
//....省略后续对已经保存的文件的操作 } catch (IOException e) {
e.printStackTrace();
}finally {
try {
if (is != null) is.close();
} catch (IOException e) { }
try
{
if (fos != null) fos.close();
} catch (IOException e)
{
}
}
}
});
}
okHttp使用的更多相关文章
- Android okHttp网络请求之Json解析
前言: 前面两篇文章介绍了基于okHttp的post.get请求,以及文件的上传下载,今天主要介绍一下如何和Json解析一起使用?如何才能提高开发效率? okHttp相关文章地址: Android o ...
- okhttp封装时,提示 cannot resolve method OkHttpClient setConnectTimeout() 函数
如标题所示,okhttp封装时,提示 cannot resolve method OkHttpClient setConnectTimeout() 函数,有遇到这样现象的朋友吗? 原因:因使用的是 ...
- RxAndroid+Retrofit+MVVM(1)OKHttp
1)Gradlecompile 'com.squareup.okhttp:okhttp:2.4.0'compile 'com.squareup.okio:okio:1.5.0' 2)Get //创建o ...
- Android okHttp网络请求之Get/Post请求
前言: 之前项目中一直使用的Xutils开源框架,从xutils 2.1.5版本使用到最近的xutils 3.0,使用起来也是蛮方便的,只不过最近想着完善一下app中使用的开源框架,由于Xutils里 ...
- Android okHttp网络请求之文件上传下载
前言: 前面介绍了基于okHttp的get.post基本使用(http://www.cnblogs.com/whoislcj/p/5526431.html),今天来实现一下基于okHttp的文件上传. ...
- Android okHttp网络请求之缓存控制Cache-Control
前言: 前面的学习基本上已经可以完成开发需求了,但是在项目中有时会遇到对请求做个缓存,当没网络的时候优先加载本地缓存,基于这个需求我们来学习一直okHttp的Cache-Control. okHttp ...
- Android okHttp网络请求之Retrofit+Okhttp+RxJava组合
前言: 通过上面的学习,我们不难发现单纯使用okHttp来作为网络库还是多多少少有那么一点点不太方便,而且还需自己来管理接口,对于接口的使用的是哪种请求方式也不能一目了然,出于这个目的接下来学习一下R ...
- 安卓学习----使用okHttp(get方式)---下载图片
一首先下载Jar包 https://github.com/square/okhttp 如果使用android studio只需要加入依赖 compile 'com.squareup.okhttp3:o ...
- Android 框架学习之 第一天 okhttp & Retrofit
最近面试,一直被问道新技术新框架,这块是短板,慢慢补吧. 关于框架的学习,分几个步骤 I.框架的使用 II.框架主流使用的版本和Android对应的版本 III.框架的衍生使用比如okhttp就会有R ...
- OkHttp简介
什么是OKHttp 一般在Java平台上,我们会使用Apache HttpClient作为Http客户端,用于发送 HTTP 请求,并对响应进行处理.比如可以使用http客户端与第三方服务(如SSO服 ...
随机推荐
- JavaScipt 事件体系
事件机制 jQuery对事件的绑定分别有几个API .bind()/.live()/.delegate()/.on() 不管是用什么方式绑定,归根到底还是用addEventListener/attac ...
- pandas筛选0,3,6开头的行
http://stackoverflow.com/questions/15325182/how-to-filter-rows-in-pandas-by-regex dbstk.loc[dbstk.ST ...
- Strategy pattern策略模式
在Java的集合框架中,经常需要通过构造方法传入一个比较器Comparator,或者创建比较器传入Collections的静态方法中作为方法参数,进行比较排序等,使用的是策略模式. 一.策略模式的定义 ...
- JAVA动手动脑
1.运行 TestInherits.java 示例,观察输出,注意总结父类与子类之间构造方法的调用关系修改Parent构造方法的代码,显式调用GrandParent的另一个构造函数,注意这句调用代码是 ...
- 【图像处理】【SEED-VPM】4.串口调试信息
—————————————————————————————————————————————————————————————————————— 串口返回正确的信息 Booting PSP Boot Lo ...
- .NET 3.5 安装错误的四个原因及解决方法
.net framework 3.5 安装错误的四个常见原因及解决方法,飓风软件站整理,转载请注明. 1.清除所有版本 .NET Framework 安装错误后在系统中遗留的文件: 如果您以往安装过 ...
- USACO 2014 JAN 滑雪录像
2. 滑雪录像{silver题3} [问题描述] 冬奥会的电视时刻表包含N (1 <= N <= 150)个节目,每个节目都有开始和结束时间.农民约翰有两台录像机,请计算他最多可以录制多少 ...
- window 链接方式
一.硬链接 mklink /H <destination> <source> 创建后的图标也和原文件的图标一样,在属性中也无法看出其中的链接关系 可通过命令查看 fsutil ...
- Bootstrap<基础九>辅助类
Bootstrap 中的一些可能会派上用场的辅助类. 文本 以下不同的类展示了不同的文本颜色.如果文本是个链接鼠标移动到文本上会变暗: 类 描述 .text-muted "text-mu ...
- OC基础--类的本质
类的本质: 类的本质其实也是一个对象(类对象),只要有了类对象, 将来就可以通过类对象来创建实例对象 程序中第一次使用该类的时候被创建,在整个程序中只有一份.此后每次使用都是这个类对象,它在程序运行时 ...