/**
网络架构分享
author kevin
本代码用于处理网络,并返回一个array,在无网络、或者网络异常情况下,可以返回当前的错误、异常不会挂掉,或者永久数据取不到,一直在显示进度条!!
*/
package com.yidaoxing.aaf.utils;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.zip.GZIPInputStream;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import android.text.TextUtils;
import com.yidaoxing.aaf.vo.RequestVo;
/**
* 联网引擎
* **/
public class HttpAgent {
public static final String ERRORCODE = "ErrorCode";
public static final String ERRORMESSAGE = "ErrorMessage";
public static int requestNum = 0;
public static InputStream is;
public static HttpResponse httpResponse;
public static String errMessage;
//处理Http头 目的为 验证
private static BasicHeader[] headers = new BasicHeader[10];
static {
headers[0] = new BasicHeader("Appkey", "");
headers[1] = new BasicHeader("Udid", "");
headers[2] = new BasicHeader("Os", "");
headers[3] = new BasicHeader("Osversion", "");
headers[4] = new BasicHeader("Appversion", "");
headers[5] = new BasicHeader("Sourceid", "");
headers[6] = new BasicHeader("Ver", "");
headers[7] = new BasicHeader("Userid", "");
headers[8] = new BasicHeader("Usersession", "");
headers[9] = new BasicHeader("Unique", "");
}
/**
* send message 首先判断是否200 如果不是200 则返回联网失败 如果是 则看errorcode和errorstring
* 如果头信息里没有两个error则返回正确数据 如果有 则返回errocode和errorstring
* @param code
*
* @param RequestVo
* vo 方法名
* @return String[] 第一个状态值 第二个文本
*/
public static synchronized String[] sendMessageByPost(RequestVo vo) {
android.os.Process
.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
DefaultHttpClient httpClinet = null;
HttpPost httpPost = null;
int code;
String response = null;
if (NetUtil.hasNetwork(vo.context)) {
return new String[] { NetUtil.CODE_HTTP_FAIL, "网络错误" };
}
try {
httpClinet = new DefaultHttpClient();
LogUtil.i("NET_ADD", Constant.APP_HOST+vo.requestUrl);
httpPost = new HttpPost(Constant.APP_HOST+vo.requestUrl);
ArrayList<NameValuePair> pair = new ArrayList<NameValuePair>();
HashMap<String, String> requestMap = vo.requestDataMap;
Iterator iterator = requestMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> entry = (Entry<String, String>) iterator
.next();
pair.add(new BasicNameValuePair(entry.getKey(), entry
.getValue()));
}
try {
httpPost.setEntity(new UrlEncodedFormEntity(pair, HTTP.UTF_8));
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
httpResponse = httpClinet.execute(httpPost);
StatusLine sl = httpResponse.getStatusLine();
// 判断服务器 响应状态
if (sl == null) {
LogUtil.i("----->>>> 第" + (requestNum++) + "次访问 -->>>");
return new String[] { NetUtil.SERVER_NOT_RESPONDING, "服务器无响应" };
}
code = sl.getStatusCode();
HttpEntity entity = httpResponse.getEntity();
// 如果数据是空的 返回 当前的code
if (entity == null) {
LogUtil.i("----->>>> 第" + (requestNum++) + "次访问 -->>>");
return new String[] { String.valueOf(code), "" };
}
// 服务器 返回的 错误 code 和 message 重要 告诉 服务器的
Header ecHeader = httpResponse.getFirstHeader(ERRORCODE);
Header emHeader = httpResponse.getFirstHeader(ERRORMESSAGE);
Header contentEncoding = httpResponse
.getFirstHeader("Content-Encoding");
String errorCode = null;
String errorMessage = null;
if (ecHeader != null) {
errorCode = ecHeader.getValue();
}
if (emHeader != null) {
errorMessage = emHeader.getValue();
}
// 如果 错误 信息 不为空 返回代码 不等于0 则返回服务器通知的错误信息
if (!TextUtils.isEmpty(errorCode)
&& !NetUtil.CODE_ERROR_RIGHT.equals(errorCode)) {
if (TextUtils.isEmpty(errorMessage)) {
errMessage = "";
} else {
try {
errMessage = new String(
errorMessage.getBytes("iso-8859-1"), "UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
LogUtil.i("----->>>> 第" + (requestNum++) + "次访问 -->>>");
return new String[] { errorCode, errMessage };
}
is = entity.getContent();
try {
if (contentEncoding != null
&& contentEncoding.getValue().equalsIgnoreCase("gzip")) {
LogUtil.i("send gzip 压缩");
response = readDataForZgip(is, "UTF-8");
} else {
LogUtil.i("无压缩");
response = readData(is, "UTF-8");
}
} catch (OutOfMemoryError e) {
// TODO: handle exception
e.printStackTrace();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
return new String[] { NetUtil.SERVER_NOT_RESPONDING, "服务器网络无响应" };
} finally {
if (httpClinet != null) {
httpClinet.getConnectionManager().shutdown();
httpClinet = null;
}
}
return new String[] { "" + code, response };
}
/**
* send message 首先判断是否200 如果不是200 则返回联网失败 如果是 则看errorcode和errorstring
* 如果头信息里没有两个error则返回正确数据 如果有 则返回errocode和errorstring
*
* @param RequestVo
* vo 方法名
* @return String[] 第一个状态值 第二个文本
*/
public static synchronized String[] sendMessageByGet(RequestVo vo) {
android.os.Process
.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
DefaultHttpClient httpClinet = null;
HttpGet httpGet = null;
// 网络错误
if (NetUtil.hasNetwork(vo.context) == false) {
return new String[] { NetUtil.CODE_HTTP_FAIL, "网络出错" };
}
int code = 0;
String response = null;
try {
httpClinet = new DefaultHttpClient();
LogUtil.i("NET_ADD", Constant.APP_HOST+vo.requestUrl);
httpGet = new HttpGet(Constant.APP_HOST+vo.requestUrl);
httpResponse = httpClinet.execute(httpGet);
StatusLine sl = httpResponse.getStatusLine();
// 判断服务器 响应状态
if (sl == null) {
LogUtil.i("----->>>> 第" + (requestNum++) + "次访问 -->>>");
return new String[] { NetUtil.SERVER_NOT_RESPONDING, "服务器无响应" };
}
code = sl.getStatusCode();
HttpEntity entity = httpResponse.getEntity();
// 如果数据是空的 返回 当前的code
if (entity == null) {
LogUtil.i("----->>>> 第" + (requestNum++) + "次访问 -->>>");
return new String[] { String.valueOf(code), "" };
}
// 服务器 返回的 错误 code 和 message 重要 告诉 服务器的
Header ecHeader = httpResponse.getFirstHeader(ERRORCODE);
Header emHeader = httpResponse.getFirstHeader(ERRORMESSAGE);
Header contentEncoding = httpResponse
.getFirstHeader("Content-Encoding");
String errorCode = null;
String errorMessage = null;
if (ecHeader != null) {
errorCode = ecHeader.getValue();
}
if (emHeader != null) {
errorMessage = emHeader.getValue();
}
// 如果 错误 信息 不为空 返回代码 不等于0 则返回服务器通知的错误信息
if (!TextUtils.isEmpty(errorCode)
&& !NetUtil.CODE_ERROR_RIGHT.equals(errorCode)) {
if (TextUtils.isEmpty(errorMessage)) {
errMessage = "";
} else {
try {
errMessage = new String(
errorMessage.getBytes("iso-8859-1"), "UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
LogUtil.i("----->>>> 第" + (requestNum++) + "次访问 -->>>");
return new String[] { errorCode, errMessage };
}
is = entity.getContent();
try {
if (contentEncoding != null
&& contentEncoding.getValue().equalsIgnoreCase("gzip")) {
LogUtil.i("send gzip 压缩");
response = readDataForZgip(is, "UTF-8");
} else {
LogUtil.i("无压缩");
response = readData(is, "UTF-8");
}
} catch (OutOfMemoryError e) {
// TODO: handle exception
e.printStackTrace();
}
} catch (Exception e) {
// TODO: handle exception
LogUtil.i("----->>>> 第" + (requestNum++) + "次访问 -->>>" + code
+ response);
e.printStackTrace();
return new String[] { NetUtil.SERVER_NOT_RESPONDING, "服务器网络无响应" };
} finally {
if (httpClinet != null) {
httpClinet.getConnectionManager().shutdown();
httpClinet = null;
}
}
LogUtil.i("----->>>> 第" + (requestNum++) + "次访问 -->>>" + code
+ response);
return new String[] { "" + code, response };
}
/**
* 第一个参数为输入流,第二个参数为字符集编码,最后返回一个字符串.
*
*/
public static String readData(InputStream inSream, String charsetName)
throws Exception {
final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
final byte[] buffer = new byte[1024];
int len = -1;
while ((len = inSream.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
final byte[] data = outStream.toByteArray();
outStream.close();
inSream.close();
return new String(data, charsetName);
}
/**
* 第一个参数为输入流,第二个参数为字符集编码
*/
public static String readDataForZgip(InputStream inStream, String charsetName)
throws Exception {
final GZIPInputStream gzipStream = new GZIPInputStream(inStream);
final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
final byte[] buffer = new byte[1024];
int len = -1;
while ((len = gzipStream.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
final byte[] data = outStream.toByteArray();
outStream.close();
gzipStream.close();
inStream.close();
return new String(data, charsetName);
}
}
/**
Netutil
直接掉 get 或 post 进行处理
*/
package com.yidaoxing.aaf.utils;
import org.json.JSONException;
import com.yidaoxing.aaf.R;
import com.yidaoxing.aaf.vo.RequestVo;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.widget.Toast;
public class NetUtil {
/** 网络出错 */
public static final String CODE_HTTP_FAIL = "-1";
/** 服务器无响应 */
public static final String SERVER_NOT_RESPONDING = "10000";
/** 联网成功 */
public static final String CODE_HTTP_SUCCEED = "200";
/** 无问题的errCode */
public static final String CODE_ERROR_RIGHT = "0";
public static String ERROR_CODE;
public static String ERROR_MESSAGE;
/**
* post post方式请求网络 如果 第一次 请求失败后 在进行第二次 请求 如果当 第二次 请求依然失败后
* 则会返回null 当返回null的情况下 我们想要得知 为什么 请求失败则,可以通过 获取本类内静态变量
* ERROR_CODE 错误值 ERROR_MESSAGE 错误消息
*
* @param RequestVo vo
* 传递进入的参数,通过该方法可以获取到 context 请求地址 传递参数 数据格式解析器
* @return obeject 返回类型 根据 解析器 返回类型 定义
* */
public static Object post(RequestVo vo) {
Object obj = null;
String[] result = HttpAgent.sendMessageByPost(vo);
// 第一次链接成功
if (result[0].equals(NetUtil.CODE_HTTP_SUCCEED)) {
try {
obj = vo.jsonParser.parseJSON(result[1]);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
HttpAgent.requestNum =0;
} else {
//链接失败 再次请求
result = HttpAgent.sendMessageByGet(vo);
if (result[0].equals(NetUtil.CODE_HTTP_SUCCEED)) {
try {
obj = vo.jsonParser.parseJSON(result[1]);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
HttpAgent.requestNum =0;
}else{
//得到服务器 处理的失败
NetUtil.ERROR_CODE = result[0];
NetUtil.ERROR_MESSAGE =result[1];
HttpAgent.requestNum =0;
}
}
return obj;
}
/**
* get get方式请求网络 如果 第一次 请求失败后 在进行第二次 请求 如果当 第二次 请求依然失败后
* 则会返回null 当返回null的情况下 我们想要得知 为什么 请求失败则,可以通过 获取本类内静态变量
* ERROR_CODE 错误值 ERROR_MESSAGE 错误消息
*
* @param RequestVo vo
* 传递进入的参数,通过该方法可以获取到 context 请求地址 数据格式解析器
* @return obeject 返回类型 根据 解析器 返回类型 定义
* */
public static Object get(RequestVo vo) {
Object obj = null;
String[] result = HttpAgent.sendMessageByGet(vo);
// 第一次链接成功
if (result[0].equals(NetUtil.CODE_HTTP_SUCCEED)) {
/*try {
obj = vo.jsonParser.parseJSON(result[1]);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
HttpAgent.requestNum =0;
} else {
//链接失败 再次请求
result = HttpAgent.sendMessageByGet(vo);
if (result[0].equals(NetUtil.CODE_HTTP_SUCCEED)) {
/*try {
obj = vo.jsonParser.parseJSON(result[1]);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
HttpAgent.requestNum =0;
}else{
//得到服务器 处理的失败
NetUtil.ERROR_CODE = result[0];
NetUtil.ERROR_MESSAGE =result[1];
HttpAgent.requestNum =0;
}
}
return obj;
}
/**
* 获得网络连接是否可用
*
* @param context
* @return
*/
public static boolean hasNetwork(Context context) {
ConnectivityManager con = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo workinfo = con.getActiveNetworkInfo();
if (workinfo == null || !workinfo.isAvailable()) {
Toast.makeText(context, R.string.net_not_connect,
Toast.LENGTH_SHORT).show();
return false;
}
return true;
}
}