天天看點

2.騰訊微網誌Android用戶端開發——Parameter類和SyncHttp類編寫

在上一節介紹的OAuth認證過程中我們可以看到我們需要不斷地和騰訊微網誌開放平台進行資料的互動,是以我們需要編寫一個類用來發送Http請求,并且能處理平台傳回過來的資料。學習Html的朋友應該知道Get和Post兩種方式送出資料,在這裡我們同樣也需要編寫Post和Get兩個方法模拟Post和Get請求。在發送微網誌時我們還可以上傳照片,是以我們還應編寫一個方法用于上傳圖檔,但是在這裡暫時還不編寫上傳資料的方法。另外在模拟Http請求時我們需要傳遞參數,是以我們需建立一個Parameter類,表示參數對象。在騰訊微網誌開放平台中關于oauth_signature參數值的産生過程介紹中有這樣一幅描述圖(http://open.t.qq.com/resource.php?i=1,2#tag0 )

2.騰訊微網誌Android用戶端開發——Parameter類和SyncHttp類編寫

我們可以看到參數對象是需要進行排序的,這裡的排序是參數按name進行字典升序排列,詳細介紹我們可以參考這篇介紹:http://wiki.opensns.qq.com/wiki/%E3%80%90QQ%E7%99%BB%E5%BD%95%E3%80%91%E7%AD%BE%E5%90%8D%E5%8F%82%E6%95%B0oauth_signature%E7%9A%84%E8%AF%B4%E6%98%8E。是以我們需讓我們的Parameter類實作 Comparable<T>接口,重寫裡面的方法,最終Parameter類代碼如下: 

package com.szy.weibo.model;
import java.io.Serializable;
/**
 *@author coolszy
 *@date 2011-5-29
 *@blog http://blog.csdn.net/coolszy
 */
public class Parameter implements Serializable, Comparable<Parameter> 
{
	private static final long serialVersionUID = 2721340807561333705L;
	
	private String name;//參數名
	private String value;//參數值

	public Parameter()
	{
		super();
	}

	public Parameter(String name, String value)
	{
		super();
		this.name = name;
		this.value = value;
	}

	public String getName()
	{
		return name;
	}

	public void setName(String name)
	{
		this.name = name;
	}

	public String getValue()
	{
		return value;
	}

	public void setValue(String value)
	{
		this.value = value;
	}

	@Override
	public String toString()
	{
		return "Parameter [name=" + name + ", value=" + value + "]";
	}

	@Override
	public boolean equals(Object arg0)
	{
		if (null == arg0)
		{
			return false;
		}
		if (this == arg0)
		{
			return true;
		}
		if (arg0 instanceof Parameter)
		{
			Parameter param = (Parameter) arg0;

			return this.getName().equals(param.getName()) && this.getValue().equals(param.getValue());
		}
		return false;
	}

	@Override
	public int compareTo(Parameter param)
	{
		int compared;
		compared = name.compareTo(param.getName());
		if (0 == compared)
		{
			compared = value.compareTo(param.getValue());
		}
		return compared;
	}
}
           

     模拟發送Http請求我們可以使用HttpURLConnection類進行操作,但是Android平台內建了功能強大且編寫更容易的commons-httpclient.jar,是以在這裡介紹如何通過commons-httpclient進行Http請求。發送Http請求可以有兩種方式:一種是同步,一種是異步。由于我對異步不是很熟悉,是以這裡先提供同步方式發送Http請求:

package com.szy.weibo.service;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.szy.weibo.model.Parameter;

/**
 *@author coolszy
 *@date 2011-5-29
 *@blog http://blog.csdn.net/coolszy
 */

/**
 * 以同步方式發送Http請求
 */
public class SyncHttp
{
	private static final Log LOG = LogFactory.getLog(SyncHttp.class);
	
	private static final int CONNECTION_TIMEOUT = 1000 * 5; // Http連接配接逾時時間

	/**
	 * 通過GET方式發送請求
	 * @param url URL位址
	 * @param params 參數
	 * @return 
	 * @throws Exception
	 */
	public String httpGet(String url, String params) throws Exception
	{
		String response = null; //傳回資訊
		if (null!=params&&!params.equals(""))
		{
			url += "?" + params;
		}
		// 構造HttpClient的執行個體
		HttpClient httpClient = new HttpClient();
		// 建立GET方法的執行個體
		GetMethod httpGet = new GetMethod(url);
		// 設定逾時時間
		httpGet.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, new Integer(CONNECTION_TIMEOUT));
		try
		{
			int statusCode = httpClient.executeMethod(httpGet);
			if (statusCode == HttpStatus.SC_OK) //SC_OK = 200
			{
				InputStream inputStream = httpGet.getResponseBodyAsStream(); //擷取輸出流,流中包含伺服器傳回資訊
				response = getData(inputStream);//擷取傳回資訊
			}
			else
			{
				LOG.debug("Get Method Statuscode : "+statusCode);
			}
		} catch (Exception e)
		{
			throw new Exception(e);
		} finally
		{
			httpGet.releaseConnection();
			httpClient = null;
		}
		return response;
	}

	/**
	 * 通過POST方式發送請求
	 * @param url URL位址
	 * @param params 參數
	 * @return
	 * @throws Exception
	 */
	public String httpPost(String url, List<Parameter> params) throws Exception
	{
		String response = null;
		HttpClient httpClient = new HttpClient();
		PostMethod httpPost = new PostMethod(url);
		//Post方式我們需要配置參數
		httpPost.addParameter("Connection", "Keep-Alive");
		httpPost.addParameter("Charset", "UTF-8");
		httpPost.addParameter("Content-Type", "application/x-www-form-urlencoded");
		httpPost.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, new Integer(CONNECTION_TIMEOUT));
		if (null!=params&¶ms.size()!=0)
		{
			//設定需要傳遞的參數,NameValuePair[]
			httpPost.setRequestBody(buildNameValuePair(params));
		}
		try
		{
			int statusCode = httpClient.executeMethod(httpPost);
			if (statusCode == HttpStatus.SC_OK)
			{
				InputStream inputStream = httpPost.getResponseBodyAsStream();
				response = getData(inputStream);
			}
			else
			{
				LOG.debug("Post Method Statuscode : "+statusCode);
			}
		} catch (Exception e)
		{
			throw new Exception(e);
		} finally
		{
			httpPost.releaseConnection();
			httpClient = null;
		}
		return response;
	}
	
	/**
	 * 建構NameValuePair數組
	 * @param params List<Parameter>集合
	 * @return
	 */
	private NameValuePair[] buildNameValuePair(List<Parameter> params)
	{
		int size = params.size();
		NameValuePair[] pair = new NameValuePair[size];
		for(int i = 0 ;i<size;i++)
		{
			Parameter param = params.get(i);
			pair[i] = new NameValuePair(param.getName(),param.getValue());
		}
		return pair;
	}
	/**
	 * 從輸入流擷取資訊
	 * @param inputStream 輸入流
	 * @return
	 * @throws Exception
	 */
	private String getData(InputStream inputStream) throws Exception
	{
		String data = "";
		//記憶體緩沖區
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		int len = -1;
		byte[] buff = new byte[1024];
		try
		{
			while((len=inputStream.read(buff))!=-1)
			{
				outputStream.write(buff, 0, len);
			}
			byte[] bytes = outputStream.toByteArray();
			data = new String(bytes);
		} catch (IOException e)
		{
			throw new Exception(e.getMessage(),e);
		}
		finally
		{
			outputStream.close();
		}
		return data;
	}
}
           

   本節課程下載下傳位址:http://u.115.com/file/aq8oydql

   本節課程文檔下載下傳:http://download.csdn.net/source/3405206