【原创】一个android访问http资源的便捷工具类——HttpHelper

HttpHelper.java

package com.newcj.net;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.*;
import org.apache.http.util.ByteArrayBuffer;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.util.Log;

/**
 * 帮助你访问 http 资源的工具类
 * 
 * @author <a href="mailto:newcj@qq.com">newcj</a>
 * @version 1.0 2010/5/9
 */
public final class HttpHelper {
	public final static String TAG = "HttpHelper";

	private final static String CONTENT_TYPE = "application/x-www-form-urlencoded";
	private final static String ACCEPT = "*/*";
	private final static String USER_AGENT = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1) Gecko/20090624 Firefox/3.5";

	/**
	 * 1024 byte
	 */
	private final static int BUFFER_LENGTH = 1024;

	private String referer;
	private Cookies cookies;
	private int timeout = 300000;

	public HttpHelper() {
		cookies = new Cookies();
	}

	/**
	 * 获取超时时间,毫秒单位,默认为300000毫秒即5分钟
	 * 
	 * @return
	 */
	public int getTimeout() {
		return timeout;
	}

	/**
	 * 设置超时时间 ReadTimeOut 与 ConnectTimeout 均设置为该超时时间,毫秒单位
	 * 
	 * @param timeout
	 */
	public void setTimeout(int timeout) {
		this.timeout = timeout;
	}

	/**
	 * 获取 Referer
	 * 
	 * @return
	 */
	public String getReferer() {
		return referer;
	}

	/**
	 * 设置 Referer
	 * 
	 * @return
	 */
	public void setReferer(String referer) {
		this.referer = referer;
	}

	/**
	 * 以GET方法新建一个线程获取网页,编码方式为 gb2312,超时或编码错误返回null
	 * 
	 * @param strUrl
	 *            网页URL地址
	 * @param handler
	 *            用于向发起本次调用的线程发送结果信息
	 * @param what
	 *            handler中的what标记
	 */
	public void getHtmlByThread(String strUrl, Handler handler, int what) {
		getHtmlByThread(strUrl, null, false, "gb2312", handler, what);
	}

	/**
	 * 以GET方法新建一个线程获取网页,超时或编码错误返回null
	 * 
	 * @param strUrl
	 *            网页URL地址
	 * @param encoding
	 *            编码方式
	 * @param handler
	 *            用于向发起本次调用的线程发送结果信息
	 * @param what
	 *            handler中的what标记
	 */
	public void getHtmlByThread(String strUrl, String encoding,
			Handler handler, int what) {
		getHtmlByThread(strUrl, null, false, encoding, handler, what);
	}

	/**
	 * 根据GET或POST方法新建一个线程获取网页,超时返回null
	 * 
	 * @param strUrl
	 *            网页URL地址
	 * @param strPost
	 *            POST 的数据
	 * @param isPost
	 *            是否 POST,true 则为POST ,false 则为 GET
	 * @param encoding
	 *            编码方式
	 * @param handler
	 *            用于向发起本次调用的线程发送结果信息
	 * @param what
	 *            handler中的what标记
	 */
	public void getHtmlByThread(String strUrl, String strPost, boolean isPost,
			String encoding, Handler handler, int what) {
		if (handler == null)
			throw new NullPointerException("handler is null.");

		Thread t = new Thread(new Runner(strUrl, strPost, isPost, encoding,
				handler, what, Runner.TYPE_HTML));
		t.setDaemon(true);
		t.start();
	}

	/**
	 * 以GET方法获取网页,编码方式为 gb2312,超时或编码错误返回null
	 * 
	 * @param strUrl
	 *            网页URL地址
	 * @return 返回网页的字符串
	 */
	public String getHtml(String strUrl) {
		return getHtml(strUrl, null, false, "gb2312");
	}

	/**
	 * 以GET方法获取网页,超时或编码错误返回null
	 * 
	 * @param strUrl
	 *            网页URL地址
	 * @param encoding
	 *            编码方式
	 * @return 返回网页的字符串
	 */
	public String getHtml(String strUrl, String encoding) {
		return getHtml(strUrl, null, false, encoding);
	}

	/**
	 * 根据GET或POST方法获取网页,超时返回null
	 * 
	 * @param strUrl
	 *            网页URL地址
	 * @param strPost
	 *            POST 的数据
	 * @param isPost
	 *            是否 POST,true 则为POST ,false 则为 GET
	 * @param encoding
	 *            编码方式
	 * @return 返回网页的字符串
	 */
	public String getHtml(String strUrl, String strPost, boolean isPost,
			String encoding) {
		String ret = null;
		try {
			byte[] data = getHtmlBytes(strUrl, strPost, isPost, encoding);
			if (data != null)
				ret = new String(data, encoding);
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
		}
		return ret;
	}

	/**
	 * 根据GET或POST方法获取网络数据,超时返回null
	 * 
	 * @param strUrl
	 *            网页URL地址
	 * @param strPost
	 *            POST 的数据
	 * @param isPost
	 *            是否POST,true则为POST,false则为 GET
	 * @param encoding
	 *            编码方式
	 * @return 返回bytes
	 */
	public byte[] getHtmlBytes(String strUrl, String strPost, boolean isPost,
			String encoding) {
		byte[] ret = null;
		HttpURLConnection httpCon = null;
		InputStream is = null;
		try {
			URL url = new URL(strUrl);
			httpCon = (HttpURLConnection) url.openConnection();
			httpCon.setReadTimeout(timeout);
			httpCon.setConnectTimeout(timeout);
			httpCon.setUseCaches(false);
			httpCon.setInstanceFollowRedirects(true);
			httpCon.setRequestProperty("Referer", referer);
			httpCon.setRequestProperty("Content-Type", CONTENT_TYPE);
			httpCon.setRequestProperty("Accept", ACCEPT);
			httpCon.setRequestProperty("User-Agent", USER_AGENT);
			httpCon.setRequestProperty("Cookie", cookies.toString());

			if (isPost) {
				httpCon.setDoOutput(true);
				httpCon.setRequestMethod("POST");
				httpCon.connect();

				OutputStream os = null;
				try {
					os = httpCon.getOutputStream();
					os.write(URLEncoder.encode(strPost, encoding).getBytes());
					os.flush();
				} finally {
					if (os != null)
						os.close();
				}
			}

			// 获取数据
			is = httpCon.getInputStream();
			ByteArrayBuffer baBuffer = null;
			byte[] buffer = new byte[BUFFER_LENGTH];
			int rNum = 0;
			// 若读取的数据长度小于 BUFFER_LENGTH,说明读取的
			// 内容小于 BUFFER_LENGTH 已经一次性读取完毕
			// 这个时候并不用创建 ByteArrayBuffer
			//
			// 以上并不适用
			// if ((rNum = is.read(buffer)) < BUFFER_LENGTH) {
			// ret = buffer;
			// } else {
			baBuffer = new ByteArrayBuffer(BUFFER_LENGTH << 1);
			// baBuffer.append(buffer, 0, BUFFER_LENGTH);
			while ((rNum = is.read(buffer)) != -1) {
				baBuffer.append(buffer, 0, rNum);
			}
			ret = baBuffer.toByteArray();
			// }

		} catch (Exception e) {
			// TODO Auto-generated catch block
			Log.e(TAG, e.getMessage() + ":" + e.getCause());
		} finally {
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block

				}
			}
			// 更新 Cookie
			if (httpCon != null) {
				cookies.putCookies(httpCon.getHeaderField("Set-Cookie"));
				// 更新 referer
				referer = strUrl;
				httpCon.disconnect();
			}
		}
		return ret;
	}

	/**
	 * 新建一个线程获取一张网页图片
	 * 
	 * @param strUrl
	 * @param handler
	 *            用于向发起本次调用的线程发送结果信息
	 * @param what
	 *            handler中的what标记
	 */
	public void getBitmapByThread(String strUrl, Handler handler, int what) {
		if (handler == null)
			throw new NullPointerException("handler is null.");

		Thread t = new Thread(new Runner(strUrl, null, false, null, handler,
				what, Runner.TYPE_IMG));
		t.setDaemon(true);
		t.start();
	}

	/**
	 * 获取一张网页图片
	 * 
	 * @param strUrl
	 *            网页图片的URL地址
	 * @return
	 */
	public Bitmap getBitmap(String strUrl) {
		byte[] data = getHtmlBytes(strUrl, null, false, null);
		return BitmapFactory.decodeByteArray(data, 0, data.length);
	}

	private class Runner implements Runnable {
		public final static int TYPE_HTML = 1;
		public final static int TYPE_IMG = 2;

		private String strUrl;
		private String strPost;
		private boolean isPost;
		private String encoding;
		private Handler handler;
		private int what;
		private int type;

		public Runner(String strUrl, String strPost, boolean isPost,
				String encoding, Handler handler, int what, int type) {
			this.strUrl = strUrl;
			this.strPost = strPost;
			this.isPost = isPost;
			this.encoding = encoding;
			this.handler = handler;
			this.what = what;
			this.type = type;
		}

		@Override
		public void run() {
			// TODO Auto-generated method stub
			Object obj = null;
			switch (type) {
			case TYPE_HTML:
				obj = getHtml(strUrl, strPost, isPost, encoding);
				break;
			case TYPE_IMG:
				obj = getBitmap(strUrl);
				break;
			}
			synchronized (handler) {
				handler.sendMessage(handler.obtainMessage(what, obj));
			}
		}

	}
}

Cookies.java

package com.newcj.net;

import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Set;

/**
 * 非同步保存Cookie的键值
 * 
 * @author SomeWind
 * 
 */
public class Cookies {

	private HashMap<String, String> hashMap;

	public Cookies() {
		hashMap = new HashMap<String, String>();
	}

	/**
	 * 清除 Cookies 里面的所有 Cookie 记录
	 */
	public void clear() {
		hashMap.clear();
	}

	/**
	 * 根据 key 获取对应的 Cookie 值
	 * 
	 * @param key
	 *            要获取的 Cookie 值的 key
	 * @return 如果不存在 key 则返回 null
	 */
	public String getCookie(String key) {
		return hashMap.get(key);
	}

	/**
	 * 在 Cookies 里设置一个 Cookie
	 * 
	 * @param key
	 *            要设置的 Cookie 的 key
	 * @param value
	 *            要设置的 Cookie 的 value
	 */
	public void putCookie(String key, String value) {
		hashMap.put(key, value);
	}

	/**
	 * 在 Cookies 里面设置传入的 cookies
	 * 
	 * @param cookies
	 */
	public void putCookies(String cookies) {
		if (cookies == null)
			return;

		String[] strCookies = cookies.split(";");
		for (int i = 0; i < strCookies.length; i++) {
			for (int j = 0; j < strCookies[i].length(); j++) {
				if (strCookies[i].charAt(j) == '=') {
					this.putCookie(
							strCookies[i].substring(0, j),
							strCookies[i].substring(j + 1,
									strCookies[i].length()));
				}
			}
		}
	}

	/**
	 * 获取 Cookies 的字符串
	 */
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		if (hashMap.isEmpty())
			return "";

		Set<Entry<String, String>> set = hashMap.entrySet();
		StringBuilder sb = new StringBuilder(set.size() * 50);
		for (Entry<String, String> entry : set) {
			sb.append(String.format("%s=%s;", entry.getKey(), entry.getValue()));
		}
		sb.delete(sb.length() - 1, sb.length());
		return sb.toString();
	}
}
posted @ 2011-05-11 13:42  newcj  阅读(4296)  评论(3编辑  收藏  举报