欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android中HttpURLConnection与HttpClient的使用与封装

程序员文章站 2024-02-24 11:42:16
1.写在前面     大部分andriod应用需要与服务器进行数据交互,http、ftp、smtp或者是直接基于socket编程都可以进行数...

1.写在前面

    大部分andriod应用需要与服务器进行数据交互,http、ftp、smtp或者是直接基于socket编程都可以进行数据交互,但是http必然是使用最广泛的协议。
    本文并不针对http协议的具体内容,仅探讨android开发中使用http协议访问网络的两种方式——httpurlconnection和httpclient
    因为需要访问网络,需在androidmanifest.xml中添加如下权限

<uses-permission android:name="android.permission.internet" />

2.httpurlconnection

2.1 get方式

import java.io.bufferedreader;
import java.io.inputstream;
import java.io.inputstreamreader;
import java.net.httpurlconnection;
import java.net.url;
 
// 以下代码实现了以get方式发起http请求
// 连接网络是耗时操作,一般新建线程进行
 
private void connectwithhttpurlconnection() {
  new thread( new runnable() {
    @override
    public void run() {
      httpurlconnection connection = null;
      try {
        // 调用url对象的openconnection方法获取httpurlconnection的实例
        url url = new url("//www.jb51.net");
        connection = (httpurlconnection) url.openconnection();
        // 设置请求方式,get或post
        connection.setrequestmethod("get");
        // 设置连接超时、读取超时的时间,单位为毫秒(ms)
        connection.setconnecttimeout(8000);
        connection.setreadtimeout(8000);
        // getinputstream方法获取服务器返回的输入流
        inputstream in = connection.getinputstream();
        // 使用bufferedreader对象读取返回的数据流
        // 按行读取,存储在stringbuider对象response中
        bufferedreader reader = new bufferedreader(new inputstreamreader(in));
        stringbuilder response = new stringbuilder();
        string line;
        while ((line = reader.readline()) != null) {
          response.append(line);
        }
        //..........
        // 此处省略处理数据的代码
        // 若需要更新ui,需将数据传回主线程,具体可搜索android多线程编程
      } catch (exception e){
        e.printstacktrace();
      } finally {
        if (connection != null){
          // 结束后,关闭连接
          connection.disconnect();
        }
      }
    }
  }).start();
}

2.2 post方式

import java.io.dataoutputstream;
 
//将对应部分改为
connection.setrequestmethod("post");
dataoutputstream data = new dataoutputstream(connection.getoutputstream());
data.writebytes("stu_no=12345&stu_name=tom");

传入多个参数用&隔开
如需传入复杂的参数,可使用json,关于json的用法介绍,可以参考我的另一篇随笔json解析的两种方法。
3.httpclient

3.1 get方式

import org.apache.http.client.httpclient;
import org.apache.http.client.methods.httpget;
import org.apache.http.impl.client.defaulthttpclient;
import org.apache.http.httpresponse;
import org.apache.http.httpentity;
import org.apache.http.httpstatus;
 
// 创建defaulthttpclient实例
httpclient httpclient = new defaulthttpclient();   
//传入网址,然后执行
httpget httpget = new httpget("//www.jb51.net");
httpresponse httpresponse = httpclient.execute(httpget); 
// 由状态码判断请求结果,
// 常见状态码 200 请求成功,404 页面未找到
// 关于http的更多状态码直接google
if (httpresponse.getstatusline().getstatuscode() == httpstatus.sc_ok) {    
  // 请求成功,使用httpentity获得返回数据
  // 使用entityutils将返回数据转换为字符串
  httpentity entity = httpresponse.getentity(); 
  string response = entityutils.tostring(entity);
  //如果是中文,指定编码 
  //==>string response = entityutils.tostring(entity, "utf-8"); 
}

3.2 post方式

import org.apache.http.client.httpclient;
import org.apache.http.client.methods.httppost;
import org.apache.http.httpresponse;
import org.apache.http.namevaluepair;
import org.apache.http.client.entity.urlencodedformentity;
import org.apache.http.message.basicnamevaluepair;
 
httpclient httpclient = new defaulthttpclient();
httppost httppost("//www.jb51.net"); 
// 使用namevaluepair(键值对)存放参数
list<namevaluepair> data = new arraylist<namevaluepair>();
// 添加键值对
data.add(new basicnamevaluepair("stu_no", 12345));
data.add(new basicnamevaluepair("stu_name", "tom"));
// 使用setentity方法传入编码后的参数
httppost.setentity(new urlencodedformentity(data, "utf-8")); 
// 执行该post请求
httpresponse httpresponse = httpclient.execute(httppost);
// .....省略处理httpresponse的代码,与get方式一致

3.3 android 6.0移除httpclient

android 6.0(api 23)版本的sdk已将apache httpclient相关类移除,解决办法自行google,推荐使用httpurlconnection。
若还需使用该类,点击查看解决办法。
4.httpurlconnection实战
如果你使用过jquery(一个javasript库),你一定对jquery的网路编程印象深刻,比如一个http请求只需以下几行代码。

// jquery的post方法
$.post("//www.jb51.net",{
    "stu_no":12345,
    "stu_name":"tom",
  }).done(function(){
    //...请求成功的代码
  }).fail(function(){
    //...请求失败的代码
  }).always(function(){
    //...总会执行的代码
  })

    我们当然不希望每次网络请求都写下2.1中那么繁琐的代码,那么android的http请求能否像jquery那么简单呢?当然可以!下面的代码实现了httpurlconnection的http请求方法封装:

4.1 定义接口httpcallbacklistener,为了实现回调

// 定义httpcallbacklistener接口
// 包含两个方法,成功和失败的回调函数定义
public interface httpcallbacklistener {
  void onfinish(string response);
  void onerror(exception e);
}

4.2 创建httptool类,抽象请求方法(get)

import java.io.bufferedreader;
import java.io.inputstream;
import java.io.inputstreamreader;
import java.net.httpurlconnection;
import java.net.url;
 
/* 创建一个新的类 httptool,将公共的操作抽象出来
 * 为了避免调用sendrequest方法时需实例化,设置为静态方法
 * 传入httpcallbacklistener对象为了方法回调
 * 因为网络请求比较耗时,一般在子线程中进行,
 * 为了获得服务器返回的数据,需要使用java的回调机制 */
 
public class httptool {
  public static void sendrequest(final string address, 
      final httpcallbacklistener listener) {
    new thread(new runnable() {
      @override
      public void run() {
        httpurlconnection connection = null;
 
        try {
          url url = new url(address);
          connection = (httpurlconnection) url.openconnection();
          connection.setrequestmethod("get");
          connection.setconnecttimeout(8000);
          connection.setreadtimeout(8000);
          inputstream in = connection.getinputstream();
          bufferedreader reader = new bufferedreader(new inputstreamreader(in));
          stringbuilder response = new stringbuilder();   string line;
          while ((line = reader.readline()) != null) {
            response.append(line);
          }
          if (listener != null) {
            // 回调方法 onfinish()
            listener.onfinish(response.tostring());
          }
        } catch (exception e) {
          if (listener != null) {
            // 回调方法 onerror()
            listener.onerror(e);
          }
        } finally {
          if (connection != null) {
            connection.disconnect();
          }
        }
      }
    }).start();
  }
}

4.3 调用示例

//使用该httptool发起get请求
string url = "//www.jb51.net";
httptool.sendrequest(url,new httpcallbacklistener(){
  @override 
  public void onfinish(string response) {
    // ...省略对返回结果的处理代码 
  } 
   
  @override 
  public void onerror(exception e) {  
    // ...省略请求失败的处理代码
  } 
});

4.4 抽象请求方法(post)

/* 在get方法实现的基础上增加一个参数params即可,
 * 将参数转换为字符串后传入
 * 也可以传入键值对集合,再处理 */
public static void sendrequest(final string address,
  final string params, final httpcallbacklistener listener){
    //...
}

以上就是本文的全部内容,希望对大家的学习有所帮助。