Android 网络通信之HTTP

注:部分整理自网络资源,部分原创。
 

Android 平台提供了3种接口用于网络的访问,分别为:

 (1).java.net.*  : 标准JAVA接口
 (2).org.apache  :Apache接口
 (3)android.net.*   :Android网络接口

  其中使用最多的就是前两种接口,以下就介绍这两个接口的基本用法。
 
 
 1.HttpURLConnection接口
 
   HttpURLConnection是Java的标准类,继承自URLConnection类,两者都是抽象类所以无法直接实例化。获取 HttpURLConnection对象,主要通过URL类的openConnection来获得。创建一个HttpURLConnection链接的标 准步骤如下代码所示:
 
  URL url = new URL("http://www.baidu.com");
  HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
 
 这样只是创建了HttpRULConnection的实例,并没有真正的进行联网的操作。因此,可以在连接之前对其进行一些参数的设置,比如:
 
  urlConnection .setRequestMethod("POST");  //设置请求方法为POST,默认为GET
  urlConnection.setUseCasches(false); //请求是否使用缓存,默认为true
 
 当连接完成后应该关闭这个链接,如下:
urlConnectin.disconnect();
 
 
以下是使用HttpURLConnectino访问网络资源的标准流程:
 
//http地址
 String httpUrl = "http://www,baidu.com";
 
StringBuffer buffer = new StringBuffer();
String line = null;
 
BufferedReader reader = null;
HttpURLConnection urlConn=null;
 
try{
     //创建URL对象
     URL url = new URL(httpUrl);
 
    //通过URL对象创建一个HttpURLConnection对象
     urlConn=(HttpURLConnection) url.openConnection();
 
    //得到读取内容的输入流
    InputStream in = new  InputStreamReader(urlConn.getInputStream());
    reader = new BufferedReader (in);
 
    while((line = reader.readLine())!=null)    //逐行读取文件,将每行是数据存入line中,当文件读取完毕后,line为null
    {
    buffer.append(line);   //逐行将line添加到StringBuffer对象中
    }
  }catch (Exception e)
      e.printStackTrace();
   }finally{
  if(reader!=null&&urlConn!=null)
                {
try {
reader.close();   //关闭BufferedReader对象
urlConn.disconnect();   //关闭HttpURLConnection对象
} catch (Exception e1) {
e1.printStackTrace();
}
}
    }
 
以 上是标准的GET请求的流程,参数的传递是直接放在URL后面;如果要使用POST,则参数要放在http请求数据中,则需要先调用 setRequestMethod设置请求类型为POST,然后将需要传递的参数内容通过writeBytes方法写入数据流中。示例如下:
 
String httUrl = "http://www.baidu.com"
 
StringBuffer buffer = new StringBuffer();
String line = null;
 
BufferedReader reader = null;
HttpURLConnection urlConn=null;
 
 
try{
     URL url = new URL(httpUrl);
 
     urlConn=(HttpURLConnection) url.openConnection();
 
     //设置请求类型
     urlConn.setRequestMethod("POST");
 
     //POST请求需要设置为true
     urlConn.setDoOutput(true);
     urlConn.setDoInput(true);
 
     //Post请求不能使用缓存
     urlConn.setUseCaches(false);
     urlConn.setInstanceFollowRedirects(true);
 
    //设置content-type获得输出流,便于向服务器发送信息。
    urlConn.setRequestProperty("Content-type","application/x-www-form-urlencoded");
    
   //获得DataOutputStream 流
   DataOutputStream out = new DataOutputStream(urlConn.getOutputStream());
 
   //要上传的参数(这里涉及到字符编码的问题)
   String content = "parameter=" + URLEncoder.encode("abcedfg","UTF-8");
  
   //将参数写入流中
   out.weiteBytes(content);
   out.flush();
   out.close();
   
    //得到读取内容的输入流
    InputStream in = new  InputStreamReader(urlConn.getInputStream());
    reader = new BufferedReader (in);
 
    while((line = reader.readLine())!=null) //逐行读取文件,将每行是数据存入line中,当文件读取完毕后,line为null
    {
    buffer.append(line);//逐行将line添加到StringBuffer对象中
    }
  }catch (Exception e)
      e.printStackTrace();
   }finally{
  if(reader!=null&&urlConn!=null)
                {
try {
reader.close();//关闭BufferedReader对象
urlConn.disconnect();//关闭HttpURLConnection对象
} catch (Exception e1) {
e1.printStackTrace();
}
}
    }
 可以看出对于POST请求,先要将参数写入输出流中,并且因为GET与POST的不同,需要在连接前设置好HttpURLConnection对象的属性,这样才能保证POST请求的顺利执行。那么获得连接后,其他的操作则和GET请求是一样的。
 
扩展:下面的方法将演示如何使用HttpURLConnection在网络上抓取一张图片,并生成Android中的Bitmap,示例如下:
 
public Bitmap CreateNetBitmap(String url)
{
 
URL imageUrl = null;
Bitmap bitmap = null;
 
InputStream in = null;
HttpURLConnection urlConn = null;
 
try{
   imageUrl = new URL(url);
   urlConn = (HttpURLConnection)imageUrl.openConnection();
   urlConn.setDoInput(true);
   urlConn.connect();
 
   InputSteam in = urlConn.getInputStream();
   bitmap = BitmapFactory.decodeStream(in);   
}catch (Exception e){
     e.printStackTrace();
    }finally{
           if(in!=null&&urlConn!=null)
                   {
try {
in.close();   //关闭流
urlConn.disconnect();   //关闭HttpURLConnection对象
        } catch (Exception e1) {
e1.printStackTrace();
}
    }  
 
    return Bitmap;
}
 
  
 
2.HttpClient接口
 
   对于标准java.net.*  可以完成一些基本的网络操作,但对于更复杂的操作,则需要用到Apache的HttpClient接口。首先需要了解一些重要的类:
      1.ClientConnectionManager  :  客户端连接管理接口,它提供了一系列的方法用于连接对象的管理。
      2.DefaultHttpClient    :一个默认的HTTP客户端,可以使用它创建一个HTTP连接
      3.HttpGet, HttpPost  : 对应 GET请求和POST请求
      4.HttpResponse :  是一个Http连接的响应。当执行一个HTTP连接后,就会返回一个HttpResponse,它封装了相应的所有信息。
 
     
 下面代码将演示如何使用HttpClient 来执行GET请求,示例如下:
 
     String httpUrl = "http://www.baidu.com?par=abcd";
     
     //创建HttpGet连接对象
     HttpGet httpRequest = new HttpGet(httpUrl);
          
    try{
            //取得HttpClient对象
            HttpClient httpClient = new DefaultHttpClient();
 
            //请求HttpClient,获得HttpResponse
            HttpResponse httpResponse = httpClient.excute(httpRequest);
 
           //判断请求是否成功
           if(httpResponse.getStatusLine().getStatusCode==HttpStatus.SC_OK)
            {
                   //取得响应的内容
                     String strResult = EntituUtils.toString(httpResponse.getEntity());
            }else{
                     System.out.println("请求出错!");
           }
     
   }catch (Exception e){
            e.printStackTrace();
        }
   
 
同 样,如果要执行POST请求,则需要先构建一个HttpPost对象,至于参数的传递,可以使用List来来保存要传递的参数对象 NameValuePair,然后用BasicNameValuePair类来构造一个需要被传递的参数,最后就是调用add方法将这个参数保存到 List中,在执行Post请求前将请求参数传递给HttpPost对象,示例如下:
 
    String httpUrl = "http://www.baidu.com?";
     
     //创建HttpPost连接对象
     HttpPost httpRequest = new HttpPostt(httpUrl);
     
   //所要传递的所有参数
   List<NameValuePair> params = new ArrayList<NameValuePair>();
   //添加参数
   params.add(new BaseNameValuePair("par","abcdefg"));
 
    try{
           //设置字符集
           HttpEntity httpEntity = new UrlEncodedFormEntity(params,"utf-8");
           
            //将请求参数赋给HttpPost对象
            httpReques.setEntity(httpEntity);
 
            //取得HttpClient对象
            HttpClient httpClient = new DefaultHttpClient();
 
            //获得HttpResponse
            HttpResponse httpResponse = httpClient.excute(httpRequest);
 
           //判断请求是否成功
           if(httpResponse.getStatusLine().getStatusCode==HttpStatus.SC_OK)
            {
                   //取得响应的内容
                     String strResult = EntituUtils.toString(httpResponse.getEntity());
            }else{
                     System.out.println("请求出错!");
           }
     
   }catch (Exception e){
            e.printStackTrace();
        }
 
(注:有些说法提出,当使用完连接后要调用 HttpGet 或者 HttpPostd的abort()方法 ,如果使用了HttpEntity对象,应该调用它的consumeContent()方法。另外一种说法,则说不需要。)
 
 
 
扩展:同样的,如果要抓取网络上的一张图片,使用HttpClient接口,应该怎么做呢?步骤与上面的演示基本一致,下面只贴出关键的步骤:
 
方法一: 获得HttpEntity对象后,通过getContent()方法获得一个输入流。
 
InputStream in  = entity.getContent();
bitmap = BitmapFactory.decodeStream(in);
in.close();
  
方法二:直接获得字节数组
 
byte [] bytes = EntityUtils.toByteArray(entity);
bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
 
真机上,两种方法都可以抓取到图片。
 
关于HttpClient以及Http协议的更多知识,可以阅读以下的文章:
 
总结:对于HttURLConnection 提供了非常简洁,快速的访问Http网络资源的方法,而HttpClient接口则提供了一套完整方案,来实现较复杂的联网操作。两者各有优缺点,可根据实际需求选择使用。
 
 
 
原文地址:https://www.cnblogs.com/xin36933/p/3554193.html