HttpPostRunnable.java 8.17 KB
package com.ectrip.trips.net;

import java.io.BufferedReader;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map.Entry;

import android.os.Handler;

import com.alibaba.fastjson.JSON;
import com.ectrip.cyt.base.DataTrans;
import com.ectrip.cyt.base.Response;
import com.ectrip.cyt.callback.HttpCallback;
import com.ectrip.cyt.config.MyApp;
import com.ectrip.cyt.utils.LogUtil;
import com.ectrip.cyt.utils.NetUtil;
import com.google.gson.Gson;

/**
 * @author jigo
 * @param <T>
 */
public class HttpPostRunnable<T> implements Runnable {
	public int timeOut = 1000 * 5;
	public int readTimeOut = 1000 * 12;

	private final String TAG = HttpPostRunnable.class.getSimpleName();
	private HttpCallback<T> resultListener;
	private String json;
	private String url;
	private String method;
	private HashMap<String, String> map;
	private Handler mHandler;
	private final int sucess = 100;
	private final int failure = 101;
	private Class<T> cls;
	private String errorData;

	public HttpPostRunnable(HttpCallback<T> resultListener, String url,
							String method, HashMap<String, String> map, Handler mHandler,
							String errorData,Class<T> cls) {
		this.resultListener = resultListener;
		this.mHandler = mHandler;
		this.url = url;
		this.method = method;
		this.map = map;
		this.cls = cls;
		this.errorData=errorData;
	}

	public void run() {
		try {
			if (resultListener == null) {
				LogUtil.i(TAG, "回调类为空,请填回调类HttpCallback");
				return;
			}
			mHandler.post(new Runnable() {
				public void run() {
					resultListener.onPreCallback(); // 加载中
				}
			});
			json = sendPost(url, method, map);
			if (json != null && json.length() > 0) {
				T object = null;
				if (resultListener != null && json != null && json.length() > 0) {
					object = parse(json, cls);
				}
				if (errorData != null) {
					// /通过类的字节码得到该类中声明的所有属性,无论私有或公有
					Field field = object.getClass().getDeclaredField(errorData);
					// 设置访问权限(这点对于有过android开发经验的可以说很熟悉)
					field.setAccessible(true);
					// 得到私有的变量值
					Object fieldObj = field.get(object); // 获取解析的变量是否为空
					if (fieldObj == null) {
							mHandler.sendMessage(mHandler.obtainMessage(failure,
									json));
						return;
					}
				}
				if (resultListener.isStoped()) {
					resultListener.onStopCallback();
					return;
				}
				if (object != null) {
					mHandler.sendMessage(mHandler.obtainMessage(sucess, object));
				} else {
					if (json.contains("CODE-")){
						mHandler.sendMessage(mHandler.obtainMessage(failure,
								json));
					}else {
						mHandler.sendMessage(mHandler.obtainMessage(failure,
								"连接服务器异常!"));
					}
				}
			} else {
				// 失败
				if (json == null) {
					mHandler.sendMessage(mHandler.obtainMessage(failure,
							"连接服务器异常!"));
				} else {
					if (json.contains("CODE-")){
						mHandler.sendMessage(mHandler.obtainMessage(failure,
								json));
					}else {
						mHandler.sendMessage(mHandler.obtainMessage(failure,
								"连接服务器异常!"));
					}
				}
			}
		} catch (Exception e) {
			if (json.contains("CODE-")){
				mHandler.sendMessage(mHandler.obtainMessage(failure,
						json));
			}else {
				mHandler.sendMessage(mHandler.obtainMessage(failure,
						"连接服务器异常!"));
			}
			throw new RuntimeException(e);
		}
	}

	/**
	 * post方式发送请求
	 *
	 * @param url
	 *            域名
	 * @param method
	 *            方法
	 * @param map
	 *            参数
	 * @return
	 */
	@SuppressWarnings("unused")
	public String sendPost(String url, String method,
						   HashMap<String, String> map) {
		StringBuffer result = new StringBuffer();
		URL realURL = null;
		BufferedReader bufReader = null;
		OutputStreamWriter out = null;
		HttpURLConnection connection = null;
		String line;
		try {
			if (method != null) {
				url += method;
			}
			realURL = new URL(url);
		} catch (MalformedURLException e) {
			LogUtil.i(TAG, "URL协议、格式或者路径错误");
			e.printStackTrace();
			return "URL协议、格式或者路径错误";
		}
		StringBuffer sb = new StringBuffer();
		if (map != null) {
			for (Entry<String, String> e : map.entrySet()) {
				try {
					sb.append(URLEncoder.encode(e.getKey(), "UTF-8"));
					sb.append("=");
					sb.append(URLEncoder.encode(e.getValue(), "UTF-8"));
					sb.append("&");
				} catch (UnsupportedEncodingException e1) {
					e1.printStackTrace();
				}
			}
			sb.substring(0, sb.length() - 1);
			try {
				LogUtil.i(TAG, sb.toString());
			} catch (Exception e1) {
				e1.printStackTrace();
			}
		}
		// 如果url不正确则返回空,这样就不会崩了
		if (realURL == null) {
			return "CODE-"+"服务器地址错误";
		}
		try {
			connection = (HttpURLConnection) realURL.openConnection();
			connection.setDoInput(true);
			connection.setDoOutput(true);
			connection.setUseCaches(false);
			connection.setConnectTimeout(timeOut);
			connection.setReadTimeout(readTimeOut);
			connection.setRequestMethod("POST");
			connection.setUseCaches(false);
			connection.setRequestProperty("accept", "*/*");
			connection.setRequestProperty("Connection", "Keep-Alive");// 这个是长链接
			connection.setRequestProperty("Charset", "UTF-8");
			connection.connect();

			out = new OutputStreamWriter(connection.getOutputStream());
			// connection.getOutputStream()这个才是连接。里面包含了connection.connect();
			if (sb.length() > 0) {
				out.write(sb.toString());
			}
			out.flush();
			out.close();
			//
		} catch (UnknownHostException e) {
			if (!NetUtil.isConnected(MyApp.getInstance())) {
				return "CODE-"+"没有连接网络";
			}
			e.printStackTrace();
			return "CODE-"+"服务地址错误或者网络超时!";
		} catch (SocketTimeoutException e) {
			e.printStackTrace();
			return "CODE-"+"连接超时!";
		} catch (IOException e) {
			if (e instanceof ConnectException) {
				return "CODE-"+"连接服务器出错!";
			}
			e.printStackTrace();
			if (e instanceof EOFException) {
				return "CODE-"+"网络不稳定";
			}
			return "CODE-"+"io流异常!";
		} catch (Exception e) {
			e.printStackTrace();
			return "CODE-"+"网络超时!";
		}

		try {
			// 获取服务器返回码
			if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
				LogUtil.v(TAG, "服务器成功返回网页");
				bufReader = new BufferedReader(new InputStreamReader(
						connection.getInputStream(), "UTF-8"));
				while ((line = bufReader.readLine()) != null) {
					result.append(line);
				}
				LogUtil.v(TAG, "返回数据:" + result.toString());
			} else if (connection.getResponseCode() == 400) {
				LogUtil.v(TAG, "服务器不理解请求的语法");
				return "CODE-"+"400错误!";
			} else if (connection.getResponseCode() == 404) {
				LogUtil.v(TAG, "服务器找不到请求的网页");
				return "CODE-"+"404错误!";
			} else if (connection.getResponseCode() == 500) {
				LogUtil.v(TAG, "服务端升级或者服务端程序有问题:500");
				return "CODE-"+"500错误!";
			} else {
				LogUtil.v(TAG, "响应失败" + connection.getResponseCode());
				return "CODE-"+"响应失败" + connection.getResponseCode();
			}
		} catch (IOException e) {
			e.printStackTrace();
			return "CODE-"+"响应失败";
		} finally {
			try {
				if (bufReader != null) {
					bufReader.close();
				}
				if (out != null) {
					out.close();
				}
				if (connection != null) {
					connection.disconnect();
				}
			} catch (IOException e2) {
				e2.printStackTrace();
			}
		}
		return result.toString();
	}

	/**
	 * 使用fast解析字符串
	 *
	 *
	 * @param json
	 * @param cls
	 * @return
	 */
	private <T> T parse(String json, Class<T> cls) {
		try {
			return JSON.parseObject(json, cls);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
}