httpUrlConnection
在Android 2.2及以下版本使用 httpURLconnection存在一些bug,所以建议在2.2及以下使用httpClient,2.3及以上使用httpUrlConnection。
**特点:
1.API简单,体积较小,因而非常适用于Android项目。
2.压缩和缓存机制可以有效地减少网络访问的流量,在提升速度和省电方面也起到了较大的作用。
**用法
1.get一般用于从服务器获取数据,post一般用于向服务器提交数据。
2.设置请求方式使用函数setRequestMethod(“POST”)进行设置。
3.获取服务器返回的输入流,使用getInputStream方法获取。
4.关闭连接,通过disconnect方法关闭当前的连接。
**get
public String get(String urlPath){
HttpURLConnection connection = null;
InputStream is = null;
try {
URL url = new URL(urlPath);
connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("GET");
//不使用缓存
connection.setUseCaches(false);
connection.setConnectTimeout(3000);
// 设置读取超时时间
connection.setReadTimeout(3000);
//设置是否从httpUrlConnection读入,默认情况下是true
connection.setDoInput(true);
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK){
is = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null){
response.append(line);
}
return response.toString();
}
} catch (Exception e) {
e.printStackTrace();
}finally {
if (connection != null){
connection.disconnect();
connection = null;
}
}
if (is != null){
try {
is.close();
is = null;
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
**post
public String post(String urlPath , Map<String , String> params){
if (params == null || params.size() == 0 ){
return get(urlPath);
}
OutputStream os = null;
InputStream is = null;
HttpURLConnection connection = null;
StringBuffer body = getParamString(params);
byte[] data = body.toString().getBytes();
try {
URL url = new URL(urlPath);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
//不使用缓存
connection.setUseCaches(false);
connection.setConnectTimeout(3000);
//设置读取超时时间
connection.setReadTimeout(3000);
//设置是否从httpUrlConnection读入,默认情况下是true
connection.setDoInput(true);
connection.setRequestProperty("Content-Type" , "application/x-www-form-urlencoded");
connection.setRequestProperty("Content-Length" , String.valueOf(data.length));
os = connection.getOutputStream();
//写入参数
os.write(data);
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK){
is = connection.getInputStream();
//包装字节流为字符流
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null){
response.append(line);
}
return response.toString();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (os != null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null){
try {
is.close();
is = null;
} catch (IOException e) {
e.printStackTrace();
}
}
if (connection != null){
connection.disconnect();
connection = null;
}
}
return null;
}
private StringBuffer getParamString(Map<String , String> params){
StringBuffer result = new StringBuffer();
Iterator<Map.Entry<String , String>> iterator = params.entrySet().iterator();
while (iterator.hasNext()){
Map.Entry<String , String> param = iterator.next();
String key = param.getKey();
String value = param.getValue();
result.append(key).append("=").append(value);
if (iterator.hasNext()){
result.append("&");
}
}
return result;
}
Okhttp
request是okhttp中访问的请求,builder是辅助类,response即okhttp中的响应
okhttp官方文档并不建议我们创建多个okhttpclient,因此全局使用一个。如果有需要,可以使用clone方法,在进行自定义。请求缓存
对网络资源进行缓存
okhttpclient client = new okhttpclient();
file sdfile = getexternalcachedir();
int cachesize = 10*1024*10;
client.setcache(new cache(sdcache.getabsolutefile(),cachesize);
request resquest = new request.builder()
.url(url)
.build();
response response1 = client.newcall(request).execute();
string body = response1.body().string();
string cache1 = response1.cacheresponse();
string newwork1 = resonse1.newworkresponse();
response response2 = client.newcall(request).execute();
string body2 = response2.body().string();
string cache2 = response2.cacheresponse();
string newwork2 = response.newworkresponse();
即使在有缓存的情况下我们依然需要去后台请求最新的资源,这个时候可以使用强制走网络来要求必须请求网络数据
request = request.newbuilder().cachecontrol(cachecontrol.force_newwork).build();
可以使用force_cache强制使用缓存数据,但如果请求必须从网络获取才有数据,但又使用了force_cache策略就会返回504错误;
request = request.newbuilder().cachecontrol(cachecontrol.force_cache).build();
取消操作
网络请求中。经常会使用到对请求的cancel操作,okhttp的也提供了这方面的接口,call的cancel操作。使用call.cancel()可以立即停止掉一个正在执行的call,如果一个线程正在写请求或者读响应,将会引发ioexecption,同时可以通过reuest.builder.tag(tag)给请求设置一个标签,并使用okhttpclient.cancel(object tag)来取消所有带有这个tag的call,但是如果该请求已经在做读写操作的时候,cancel是无法成功的,会抛出ioexecption异常
call call = client.newcall(request);
executor.schedule(new runnable(){
public void run(){
call.cancel();
}
},1,timeunit.seconds};
response response = call.execte();
http post提交json数据
public static final MediaType JSON = MediaType.parse("application/json;charset=utf-8");
OkHttpClient client = new OkHttpClient();
string Post(strint url , string json){
requestbody body = requestbody.create(JSON , json);
request request = new request.builder().url(url).post(body).build();
response response = client.newcall(request).execute();
if(reponse.issuccessful()){
return response.body().string();
}
}
okhttp通过post方式把键值对数据传送到服务器
okhttpclient client = new okhttpclient();
string post(string url , string json){
requestbody body = new formencodingbuilder()
.add("platform" , "android")
.add("name","bug")
.add("subject","xxxx").builder();
request request = new request.Builder().url (url).post(body).builder();
response response = client.newcall(request).excute();}
synchronous get(同步get)
下载一个文件,响应体的string()方法对于小文档来说十分方便、高效。但是如果响应体太大(超过1M),应避免使用string()方法,因为它会把整个文档加载到内存中,对于超过MB的响应body,应使用流的方式处理body
okhttpclient client = new okhttpclient();
public void run(){
request request = new request.builder()
.url("http://publicobject.com/helloworld.txt")
.builder();
response response = client.newcall(request).excute();
headers headers = response.headers();
string headerName = headers.name();
string body = response.body.string();
}
asynchronous get(异步get)
在一个工作线程中下载文件时,当响应可读时回调callback接口是,读取响应时会阻塞当前线程,okhttp现阶段不提供异步api来接收响应体。
okhttpclient client = new okhttpclient();
public void run(){
request request = new request.builder()
.url(url)
.builder();
client.newcall(request).enqueue(new callback(){
public void onresponse(call call,response response){
headers headers = response.headers();
for(int i=0;i<headers.size();i++){
string name = headers.name(i);
string value = headers.value(i);
}
string body = response.body().string();
}
});
}
post streaming(post方式提交流)
以流的方式post提交请求体,请求体的内容有流写入产生,这个例子是流直接写入okio的bufferedsink。程序可能会使用outputstream,可以使用bufferedsink.outputstream()来获取。
mediatype type = mediatype.parse("text/x-markdown ; charset=utf-8");
okhttpclient client = new okhttpclient();
public void run(){
requestbody body = new requestbody(){
public mediatype contenttype(){
return MEDIA_THPE_MARKDOWN;
}
public void writeto(bufferdsink sink){
sink.writeutf8("numbers\n);
sink.writeutf8("-----\n");
for(int i=0;i<+997;i++){
skin.writeutf8(string format("*%s = %s\n",i,foctor(i)))
}
}
private string factor(int n ){
for (int i=2;i<n;i++{
int x= n/i;
if(x*i == n)return factor(x)+"x"+i;
}
return integer.tostring(n);
}
};
request request = new request.builder()
.url(url)
.post(body)
.build();
response response = client.newcall(request).excute();
response responsebody = response.body().string();
}
posting a file(post 方式提交文件)
mediatype type = mediatype.creat("text/x-markdown" , charset=utf-8);
okhttpclient client = new okhttpclient();
public void run(){
file file = new file("readme.md");
request request = new request.builder() .url(url) .post(requestbody.create(media_type_markdown,file)
.build();
response response= client.newcall(request).execute();
string responsebody = response.body().string();
}
使用formencodingbuilder来构建和html标签相同效果的请求体。键值对将使用一种html兼容的形式的URL编码来进行编码。
okhttpclient client =new okhttpclient();
public void run (){
requestbody body = new formbody.builder()
.add("search","Jurassic Park")
.build();
request request = new request.buider()
.url(url)
.post(body)
.build();
response response = client.newcall(request).excute();
string responsebody = response.body();
}
okhttp中的坑
没有帮我缓存并发送cookie给服务器
1.okhttp 3.0开始,默认不保存cookie,要自己使用cookiejar来保存cookie。
2.使用builder来构建okhttpclient才能设置cookiejar。
3.使用下面的代码可以帮你自动管理cooKie
//记录下正确姿势
OkHttpClient mHttpClient = new OkHttpClient.Builder().cookieJar(new CookieJar() {
private final HashMap