HttpHelper.java
  001 package com.newcj.net;
  002
  003 import java.io.IOException;
  004 import java.io.InputStream;
  005 import java.io.OutputStream;
  006 import java.io.UnsupportedEncodingException;
  007 import java.net.*;
  008 import org.apache.http.util.ByteArrayBuffer;
  009
  010 import android.graphics.Bitmap;
  011 import android.graphics.BitmapFactory;
  012 import android.os.Handler;
  013 import android.util.Log;
  014
  015 /**
  016 * 帮助你访问 http 资源的工具类
  017 *
  018 * @author <a href=" mailto:newcj@qq.com">newcj</a>
  019 * @version 1.0 2010/5/9
  020 */
  021 public final class HttpHelper {
  022 public final static String TAG = "HttpHelper";
  023
  024 private final static String CONTENT_TYPE = "application/x-www-form-urlencoded";
  025 private final static String ACCEPT = "*/*";
  026 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";
  027
  028 /**
  029 * 1024 byte
  030 */
  031 private final static int BUFFER_LENGTH = 1024;
  032
  033 private String referer;
  034 private Cookies cookies;
  035 private int timeout = 300000;
  036
  037 public HttpHelper() {
  038 cookies = new Cookies();
  039 }
  040
  041 /**
  042 * 获取超时时间,毫秒单位,默认为300000毫秒即5分钟
  043 *
  044 * @return
  045 */
  046 public int getTimeout() {
  047 return timeout;
  048 }
  049
  050 /**
  051 * 设置超时时间 ReadTimeOut 与 ConnectTimeout 均设置为该超时时间,毫秒单位
  052 *
  053 * @param timeout
  054 */
  055 public void setTimeout(int timeout) {
  056 this.timeout = timeout;
  057 }
  058
  059 /**
  060 * 获取 Referer
  061 *
  062 * @return
  063 */
  064 public String getReferer() {
  065 return referer;
  066 }
  067
  068 /**
  069 * 设置 Referer
  070 *
  071 * @return
  072 */
  073 public void setReferer(String referer) {
  074 this.referer = referer;
  075 }
  076
  077 /**
  078 * 以GET方法新建一个线程获取网页,编码方式为 gb2312,超时或编码错误返回null
  079 *
  080 * @param strUrl
  081 * 网页URL地址
  082 * @param handler
  083 * 用于向发起本次调用的线程发送结果信息
  084 * @param what
  085 * handler中的what标记
  086 */
  087 public void getHtmlByThread(String strUrl, Handler handler, int what) {
  088 getHtmlByThread(strUrl, null, false, "gb2312", handler, what);
  089 }
  090
  091 /**
  092 * 以GET方法新建一个线程获取网页,超时或编码错误返回null
  093 *
  094 * @param strUrl
  095 * 网页URL地址
  096 * @param encoding
  097 * 编码方式
  098 * @param handler
  099 * 用于向发起本次调用的线程发送结果信息
  100 * @param what
  101 * handler中的what标记
  102 */
  103 public void getHtmlByThread(String strUrl, String encoding,
  104 Handler handler, int what) {
  105 getHtmlByThread(strUrl, null, false, encoding, handler, what);
  106 }
  107
  108 /**
  109 * 根据GET或POST方法新建一个线程获取网页,超时返回null
  110 *
  111 * @param strUrl
  112 * 网页URL地址
  113 * @param strPost
  114 * POST 的数据
  115 * @param isPost
  116 * 是否 POST,true 则为POST ,false 则为 GET
  117 * @param encoding
  118 * 编码方式
  119 * @param handler
  120 * 用于向发起本次调用的线程发送结果信息
  121 * @param what
  122 * handler中的what标记
  123 */
  124 public void getHtmlByThread(String strUrl, String strPost, boolean isPost,
  125 String encoding, Handler handler, int what) {
  126 if (handler == null)
  127 throw new NullPointerException("handler is null.");
  128
  129 Thread t = new Thread(new Runner(strUrl, strPost, isPost, encoding,
  130 handler, what, Runner.TYPE_HTML));
  131 t.setDaemon(true);
  132 t.start();
  133 }
  134
  135 /**
  136 * 以GET方法获取网页,编码方式为 gb2312,超时或编码错误返回null
  137 *
  138 * @param strUrl
  139 * 网页URL地址
  140 * @return 返回网页的字符串
  141 */
  142 public String getHtml(String strUrl) {
  143 return getHtml(strUrl, null, false, "gb2312");
  144 }
  145
  146 /**
  147 * 以GET方法获取网页,超时或编码错误返回null
  148 *
  149 * @param strUrl
  150 * 网页URL地址
  151 * @param encoding
  152 * 编码方式
  153 * @return 返回网页的字符串
  154 */
  155 public String getHtml(String strUrl, String encoding) {
  156 return getHtml(strUrl, null, false, encoding);
  157 }
  158
  159 /**
  160 * 根据GET或POST方法获取网页,超时返回null
  161 *
  162 * @param strUrl
  163 * 网页URL地址
  164 * @param strPost
  165 * POST 的数据
  166 * @param isPost
  167 * 是否 POST,true 则为POST ,false 则为 GET
  168 * @param encoding
  169 * 编码方式
  170 * @return 返回网页的字符串
  171 */
  172 public String getHtml(String strUrl, String strPost, boolean isPost,
  173 String encoding) {
  174 String ret = null;
  175 try {
  176 byte[] data = getHtmlBytes(strUrl, strPost, isPost, encoding);
  177 if (data != null)
  178 ret = new String(data, encoding);
  179 } catch (UnsupportedEncodingException e) {
  180 // TODO Auto-generated catch block
  181 }
  182 return ret;
  183 }
  184
  185 /**
  186 * 根据GET或POST方法获取网络数据,超时返回null
  187 *
  188 * @param strUrl
  189 * 网页URL地址
  190 * @param strPost
  191 * POST 的数据
  192 * @param isPost
  193 * 是否POST,true则为POST,false则为 GET
  194 * @param encoding
  195 * 编码方式
  196 * @return 返回bytes
  197 */
  198 public byte[] getHtmlBytes(String strUrl, String strPost, boolean isPost,
  199 String encoding) {
  200 byte[] ret = null;
  201 HttpURLConnection httpCon = null;
  202 InputStream is = null;
  203 try {
  204 URL url = new URL(strUrl);
  205 httpCon = (HttpURLConnection) url.openConnection();
  206 httpCon.setReadTimeout(timeout);
  207 httpCon.setConnectTimeout(timeout);
  208 httpCon.setUseCaches(false);
  209 httpCon.setInstanceFollowRedirects(true);
  210 httpCon.setRequestProperty("Referer", referer);
  211 httpCon.setRequestProperty("Content-Type", CONTENT_TYPE);
  212 httpCon.setRequestProperty("Accept", ACCEPT);
  213 httpCon.setRequestProperty("User-Agent", USER_AGENT);
  214 httpCon.setRequestProperty("Cookie", cookies.toString());
  215
  216 if (isPost) {
  217 httpCon.setDoOutput(true);
  218 httpCon.setRequestMethod("POST");
  219 httpCon.connect();
  220
  221 OutputStream os = null;
  222 try {
  223 os = httpCon.getOutputStream();
  224 os.write(URLEncoder.encode(strPost, encoding).getBytes());
  225 os.flush();
  226 } finally {
  227 if (os != null)
  228 os.close();
  229 }
  230 }
  231
  232 // 获取数据
  233 is = httpCon.getInputStream();
  234 ByteArrayBuffer baBuffer = null;
  235 byte[] buffer = new byte[BUFFER_LENGTH];
  236 int rNum = 0;
  237 // 若读取的数据长度小于 BUFFER_LENGTH,说明读取的
  238 // 内容小于 BUFFER_LENGTH 已经一次性读取完毕
  239 // 这个时候并不用创建 ByteArrayBuffer
  240 //
  241 // 以上并不适用
  242 // if ((rNum = is.read(buffer)) < BUFFER_LENGTH) {
  243 // ret = buffer;
  244 // } else {
  245 baBuffer = new ByteArrayBuffer(BUFFER_LENGTH << 1);
  246 // baBuffer.append(buffer, 0, BUFFER_LENGTH);
  247 while ((rNum = is.read(buffer)) != -1) {
  248 baBuffer.append(buffer, 0, rNum);
  249 }
  250 ret = baBuffer.toByteArray();
  251 // }
  252
  253 } catch (Exception e) {
  254 // TODO Auto-generated catch block
  255 Log.e(TAG, e.getMessage() + ":" + e.getCause());
  256 } finally {
  257 if (is != null) {
  258 try {
  259 is.close();
  260 } catch (IOException e) {
  261 // TODO Auto-generated catch block
  262
  263 }
  264 }
  265 // 更新 Cookie
  266 if (httpCon != null) {
  267 cookies.putCookies(httpCon.getHeaderField("Set-Cookie"));
  268 // 更新 referer
  269 referer = strUrl;
  270 httpCon.disconnect();
  271 }
  272 }
  273 return ret;
  274 }
  275
  276 /**
  277 * 新建一个线程获取一张网页图片
  278 *
  279 * @param strUrl
  280 * @param handler
  281 * 用于向发起本次调用的线程发送结果信息
  282 * @param what
  283 * handler中的what标记
  284 */
  285 public void getBitmapByThread(String strUrl, Handler handler, int what) {
  286 if (handler == null)
  287 throw new NullPointerException("handler is null.");
  288
  289 Thread t = new Thread(new Runner(strUrl, null, false, null, handler,
  290 what, Runner.TYPE_IMG));
  291 t.setDaemon(true);
  292 t.start();
  293 }
  294
  295 /**
  296 * 获取一张网页图片
  297 *
  298 * @param strUrl
  299 * 网页图片的URL地址
  300 * @return
  301 */
  302 public Bitmap getBitmap(String strUrl) {
  303 byte[] data = getHtmlBytes(strUrl, null, false, null);
  304 return BitmapFactory.decodeByteArray(data, 0, data.length);
  305 }
  306
  307 private class Runner implements Runnable {
  308 public final static int TYPE_HTML = 1;
  309 public final static int TYPE_IMG = 2;
  310
  311 private String strUrl;
  312 private String strPost;
  313 private boolean isPost;
  314 private String encoding;
  315 private Handler handler;
  316 private int what;
  317 private int type;
  318
  319 public Runner(String strUrl, String strPost, boolean isPost,
  320 String encoding, Handler handler, int what, int type) {
  321 this.strUrl = strUrl;
  322 this.strPost = strPost;
  323 this.isPost = isPost;
  324 this.encoding = encoding;
  325 this.handler = handler;
  326 this.what = what;
  327 this.type = type;
  328 }
  329
  330 @Override
  331 public void run() {
  332 // TODO Auto-generated method stub
  333 Object obj = null;
  334 switch (type) {
  335 case TYPE_HTML:
  336 obj = getHtml(strUrl, strPost, isPost, encoding);
  337 break;
  338 case TYPE_IMG:
  339 obj = getBitmap(strUrl);
  340 break;
  341 }
  342 synchronized (handler) {
  343 handler.sendMessage(handler.obtainMessage(what, obj));
  344 }
  345 }
  346
  347 }
  348 }
  Cookies.java
  01 package com.newcj.net;
  02
  03 import java.util.HashMap;
  04 import java.util.Map.Entry;
  05 import java.util.Set;
  06
  07 /**
  08 * 非同步保存Cookie的键值
  09 *
  10 * @author SomeWind
  11 *
  12 */
  13 public class Cookies {
  14
  15 private HashMap<String, String> hashMap;
  16
  17 public Cookies() {
  18 hashMap = new HashMap<String, String>();
  19 }
  20
  21 /**
  22 * 清除 Cookies 里面的所有 Cookie 记录
  23 */
  24 public void clear() {
  25 hashMap.clear();
  26 }
  27
  28 /**
  29 * 根据 key 获取对应的 Cookie 值
  30 *
  31 * @param key
  32 * 要获取的 Cookie 值的 key
  33 * @return 如果不存在 key 则返回 null
  34 */
  35 public String getCookie(String key) {
  36 return hashMap.get(key);
  37 }
  38
  39 /**
  40 * 在 Cookies 里设置一个 Cookie
  41 *
  42 * @param key
  43 * 要设置的 Cookie 的 key
  44 * @param value
  45 * 要设置的 Cookie 的 value
  46 */
  47 public void putCookie(String key, String value) {
  48 hashMap.put(key, value);
  49 }
  50
  51 /**
  52 * 在 Cookies 里面设置传入的 cookies
  53 *
  54 * @param cookies
  55 */
  56 public void putCookies(String cookies) {
  57 if (cookies == null)
  58 return;
  59
  60 String[] strCookies = cookies.split(";");
  61 for (int i = 0; i < strCookies.length; i++) {
  62 for (int j = 0; j < strCookies[i].length(); j++) {
  63 if (strCookies[i].charAt(j) == '=') {
  64 this.putCookie(
  65 strCookies[i].substring(0, j),
  66 strCookies[i].substring(j + 1,
  67 strCookies[i].length()));
  68 }
  69 }
  70 }
  71 }
  72
  73 /**
  74 * 获取 Cookies 的字符串
  75 */
  76 @Override
  77 public String toString() {
  78 // TODO Auto-generated method stub
  79 if (hashMap.isEmpty())
  80 return "";
  81
  82 Set<Entry<String, String>> set = hashMap.entrySet();
  83 StringBuilder sb = new StringBuilder(set.size() * 50);
  84 for (Entry<String, String> entry : set) {
  85 sb.append(String.format("%s=%s;", entry.getKey(), entry.getValue()));
  86 }
  87 sb.delete(sb.length() - 1, sb.length());
  88 return sb.toString();
  89 }
  90 }