在上一节介绍的OAuth认证过程中我们可以看到我们需要不断地和腾讯微博开放平台进行数据的交互,因此我们需要编写一个类用来发送Http请求,并且能处理平台返回过来的数据。学习Html的朋友应该知道GetPost两种方式提交数据,在这里我们同样也需要编写PostGet两个方法模拟PostGet请求。在发送微博时我们还可以上传照片,所以我们还应编写一个方法用于上传图片,但是在这里暂时还不编写上传数据的方法。另外在模拟Http请求时我们需要传递参数,因此我们需创建一个Parameter类,表示参数对象。在腾讯微博开放平台中关于oauth_signature参数值的产生过程介绍中有这样一幅描述图(http://open.t.qq.com/resource.php?i=1,2#tag0 )

我们可以看到参数对象是需要进行排序的,这里的排序是参数按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

作者: coolszy 发表于 2011-06-04 12:50 原文链接

推荐.NET配套的通用数据层ORM框架:CYQ.Data 通用数据层框架
新浪微博粉丝精灵,刷粉丝、刷评论、刷转发、企业商家微博营销必备工具"