package com.exmyth.net; public interface KeyLoadListener { public void onSuccess(byte[] key); // public void onFailure(int statusCode, String content); }
package com.exmyth.net; public abstract class LoadDataHandler { /** * 加载数据时调用 */ public void onStart() {}; /** * 加载数据调用,得到缓存数据 * * @param data */ // protected void onLoadCaches(String data) {}; /** * 当调用服务器接口成功获取数据时,调用这个方法 * * @param data */ public abstract void onSuccess(String data); /** * 当调用服务器接口获取数据失败时,调用这个方法 * * @param statusCode * 出错原因 * @param message * 出错原因描述 */ public void onFailure(int statusCode, String message) { }; /** * 加载完成时调用 */ public void onFinish() { } protected void onSuccess(byte[] content) { this.onSuccess(new String(content)); } protected void onFailure(int statusCode, byte[] content) { this.onFailure(statusCode,new String(content)); } }
package com.exmyth.net; import org.apache.http.Header; import com.loopj.android.http.AsyncHttpResponseHandler; public class WPHttpResponseHandler extends AsyncHttpResponseHandler { private LoadDataHandler mHandler; public WPHttpResponseHandler(LoadDataHandler mHandler) { this.mHandler = mHandler; } @Override public void onStart() { super.onStart(); mHandler.onStart(); } @Override public void onFailure(int statusCode, Header[] headers, byte[] content, Throwable error) { // TODO Auto-generated method stub super.onFailure(statusCode, headers, content, error); // if (content != null && 0 < content.length ) { mHandler.onFailure(statusCode, content); // } } @Override public void onFinish() { super.onFinish(); mHandler.onFinish(); } @Override public void onSuccess(int statusCode, Header[] headers, byte[] content) { super.onSuccess(statusCode, headers, content); switch (statusCode) { case 200: // if (content != null && 0 < content.length ) { mHandler.onSuccess(content); // } break; case 401: mHandler.onFailure(401, "没有登录"); break; case 403: mHandler.onFailure(403, "没有权限"); break; default: break; } } }
package com.exmyth.utils; import com.exmyth.net.KeyLoadListener; import com.exmyth.net.LoadDataHandler; import com.exmyth.net.WPHttpResponseHandler; public class HttpUtils{ private static String versionId = "24"; private static String appVersion = "24";//当前的appVersion,如果版本过低,会有强制更新提示 private static final String CLIENT_KEY_STORE_PASSWORD = "198345"; private static Context mContext; private static AsyncHttpClient client =new AsyncHttpClient(); //实例话对象 public static byte[] key = null; public static boolean encrypt = false; public HttpUtils(Context context){ mContext = context; client.setTimeout(10000); //设置链接超时,如果不设置,默认为10s PersistentCookieStore myCookieStore = new PersistentCookieStore(mContext); BasicClientCookie newCookie = new BasicClientCookie("name", CommonUtil.mac); newCookie.setVersion(1); newCookie.setDomain("mydomain.com"); newCookie.setPath("/"); myCookieStore.addCookie(newCookie); client.setCookieStore(myCookieStore); try { KeyStore keystore = KeyStore.getInstance("BKS"); keystore.load(mContext.getResources().openRawResource( R.raw.client), CLIENT_KEY_STORE_PASSWORD.toCharArray()); KeyStore trustkeystore = KeyStore.getInstance("BKS"); trustkeystore.load(mContext.getResources().openRawResource( R.raw.server_trust), CLIENT_KEY_STORE_PASSWORD.toCharArray()); SSLSocketFactory factory = new SSLSocketFactory(keystore, CLIENT_KEY_STORE_PASSWORD, trustkeystore); Scheme sch = new Scheme("https", factory, 443); client.getHttpClient().getConnectionManager().getSchemeRegistry().register(sch); }catch(Exception e){ e.printStackTrace(); } } public static void post(final String url, final Map<String, String> param,final LoadDataHandler callback) { if(encrypt && null != param && 0 < param.keySet().size()){ if (key == null) { getKey(0, callback, new KeyLoadListener() { @Override public void onSuccess(byte[] key) { doPost(0, url, key,param, callback); } }); } else{ doPost(0, url, key,param, callback); } }else{ doPost(0, url, null,param, callback); } } //3000 获取key的接口失败(onFailure) //4000 app问题,请求失败 //5000 获取key的接口不能顺利请求(statusCode != 200) //5100 服务器端getKey异常 //5200 服务器端返回结果不合法,或者APP解析结果异常 //5300 从服务端获取的key是空的(TextUtils.isEmpty(key)==true) //6000 第一次请求获取key失败 //7000 获取到key后,第二请求后仍然失效 //8000 {success:false}正常aes加密/非加密请求,但是success为false //8100 第二次请求aes加密请求仍然失败 //8200 服务器端返回结果不合法,或者APP解析结果异常 private static void doPost(final int index, final String url, byte[] key, final Map<String, String> param , final LoadDataHandler callback) { if (1 < index) { callback.onFailure(7000, "获取到key后,第二请求后仍然失效"); } RequestParams requestParams = new RequestParams(); if(null != param && 0 < param.keySet().size()&& null != key && 0 < key.length){ AESUtil aes = new AESUtil(key); for (Map.Entry<String, String> entry : param.entrySet()) { requestParams.put(entry.getKey(), defaultEncodeBase64String(aes, entry.getValue())); } } //无参数,不需要做aes加密 requestParams.put("versionId", versionId); client.post(url, requestParams, new WPHttpResponseHandler( new LoadDataHandler() { @Override public void onSuccess(String data) { try { JSONObject result = new JSONObject(data); if("true".equals(result.optString("success"))){ callback.onSuccess(data); } else{ //{"errMsg":"Aes Decode error","errorCode":"255","success":false} if ("255".equals(result.optString("errorCode"))) { if(0 < index){ callback.onFailure(8100, "第二次请求aes加密请求仍然失败"); } else{ //第一次请求aes加密请求失败,就请求获取key继续调用接口 getKey(0, callback,new KeyLoadListener() { @Override public void onSuccess(byte[] key) { doPost((index+1), url, key, param, callback); } }); } } else{ //{success:false}正常aes加密/非加密请求,但是success为false callback.onFailure(8000, data); } } } catch (JSONException e) { // e.printStackTrace(); callback.onFailure(8200, data); } } @Override public void onFailure(int statusCode, String message) { super.onFailure(statusCode, message); callback.onFailure(4000, message); } })); } //获得key private static void getKey(final int index, final LoadDataHandler callback, final KeyLoadListener listener) { if (0 < index) { callback.onFailure(6000, "第一次请求获取key失败"); } else{ client.post(RequestConfig.Key_URL, null, new AsyncHttpResponseHandler(){ @Override public void onSuccess(int statusCode,Header[] headers, byte[] content) { if(200 == statusCode){ try { JSONObject jsonObject = new JSONObject(new String(content)); String success = jsonObject.optString("success"); //{"data":"1234567890ABCDEF1234567890ABCDEF","success":true} if("true".equals(success)){ String data = jsonObject.optString("data"); if (!TextUtils.isEmpty(data)) { key = Base64.decodeBase64(data.getBytes()); listener.onSuccess(key); } else{ // getKey((index + 1), callback,listener); // listener.onFailure(5300,"从服务端获取的key是空的(TextUtils.isEmpty(key)==true)"); callback.onFailure(5300, "从服务端获取的key是空的(TextUtils.isEmpty(key)==true)"); } } else{ //{"errMsg":"errorCode","success":false} callback.onFailure(5100, "服务器端getKey异常"); //getKey((index + 1), callback,listener); } } catch (JSONException e) { // e.printStackTrace(); callback.onFailure(5200, "服务器端返回结果不合法,或者APP解析结果异常"); } } else{ callback.onFailure(5000, "获取key的接口不能顺利请求(statusCode != 200)"); } } @Override public void onFailure(int statusCode, Header[] headers, byte[] content, Throwable error) { super.onFailure(statusCode, headers, content, error); // getKey((index + 1), callback,listener); callback.onFailure(3000, "获取key的接口失败(onFailure)"); } }); } } // 加密密码 public static String md5(String str) { MessageDigest messageDigest = null; try { messageDigest = MessageDigest.getInstance("MD5"); messageDigest.reset(); messageDigest.update(str.getBytes("UTF-8")); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } byte[] byteArray = messageDigest.digest(); StringBuffer md5StrBuff = new StringBuffer(); for (int i = 0; i < byteArray.length; i++) { if (Integer.toHexString(0xFF & byteArray[i]).length() == 1) md5StrBuff.append("0").append( Integer.toHexString(0xFF & byteArray[i])); else md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i])); } return md5StrBuff.toString(); } //获取默认请求参数字节 private static String defaultEncodeBase64String(AESUtil aes, String param){ //如果是加密请求,调动此方法 return encodeBase64String(true,aes,param); //如果是非加密请求,调动此方法 // return encodeBase64String(false,null,param); } private static String encodeBase64String(boolean encrypt,AESUtil aes, String param){ if(null == param){ return null; } if(encrypt){ if(null == aes){ if (null == key){ key = "123456789001234567891234567890CD".getBytes(); } aes = new AESUtil(key); } return Base64.encodeBase64String(aes.aesEncrypt(param.getBytes())); } // return Base64.encodeBase64String(param.getBytes()); return param; } }