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;
} }

HttpClient封装的更多相关文章

  1. .Net基础——程序集与CIL HttpClient封装方法 .Net Core 编码规范 C#中invoke和beginInvoke的使用 WebServeice 动态代理类

    .Net基础——程序集与CIL   1. 程序集和CIL: 程序集是由.NET语言的编译器接受源代码文件产生的输出文件,通常分为 exe和dll两类,其中exe包含Main入口方法可以双击执行,dll ...

  2. java使用httpclient封装post请求和get的请求

    在我们程序员生涯中,经常要复用代码,所以我们应该养成时常整理代码的好习惯,以下是我之前封装的httpclient的post和get请求所用的代码: package com.marco.common; ...

  3. .Net Standard HttpClient封装Htt请求常用操作整理

    一.常用Http操作 1.Get请求,有参数,无参数 2.Post 请求,有参数,无参数 3.文件简单下载 修改NetHelper中Post请求方法Bug:请求编码默认UTF8,字符串内存流读取后这是 ...

  4. HttpClient封装工具类

    import java.io.IOException; import java.net.URI; import java.util.ArrayList; import java.util.List; ...

  5. HttpClient封装方法

    //post请求 public static string PostRequest(string url, HttpContent data) { var handler = new HttpClie ...

  6. android和httpClient

    一.说起来都是泪 各大组织不同步,可是我想用别人的库. 二.谷歌和阿帕奇的爱恨情仇 初,谷歌安卓新出,库中自带HttpClient 4.0测试预览版.为与安卓保持API同步,HTTPClient不敢大 ...

  7. HTTP访问的两种方式(HttpClient+HttpURLConnection)整合汇总对比(转)

    在Android上http 操作类有两种,分别是HttpClient和HttpURLConnection,其中两个类的详细介绍可以问度娘. HttpClient: HttpClient是Apache ...

  8. android中的HttpURLConnection和HttpClient实现app与pc数据交互

    自学android的这几天很辛苦,但是很满足,因为每当学到一点点知识点都会觉得很开心,觉得今天是特别有意义的,可能这个就是一种莫名的热爱吧. 下面来说说今天学习的HttpURLConnection和H ...

  9. Android--Apache HttpClient

    前言 上一篇文章介绍了使用HttpURLConnection来完成对于HTTP协议的支持.现在介绍一个新的方式来访问Web站点,那就是HttpClient. HttpClient是Apache开源组织 ...

随机推荐

  1. Java POI 两种导出方式

    这里面包含了模板导出方法和自定义模板进行导出 package jp.co.syspro.poo.action.hibikoyou; import java.io.ByteArrayOutputStre ...

  2. c#中去掉字符串空格方法

    (1)Trim方法 string   tt=" aaa "; tt=tt.Trim()       去字符串首尾空格的函数 tt=tt.TrimEnd() 去掉字符串尾空格 tt= ...

  3. 推送:腾迅信鸽 VS Bmob

    最近几天了解市场上主流的推送SDK. 腾迅信鸽 所需SDK,去官网自行下载.去下载 完整的清单文件如下: <?xml version="1.0" encoding=" ...

  4. PT与PX,em(%)区别

    字体大小的设置单位,常用的有2种:px.pt.这两个有什么区别呢?先搞清基本概念:px就是表示pixel,像素,是屏幕上显示数据的最基本的点:pt就是point,是印刷行业常用单位,等于1/72英寸. ...

  5. Xcode7 通过 Single View Application 得到一个 Empty Application 工程

    方法: 创建一个 Empty Application 工程 下面还是详细的说一下通过一个 Single View Application 工程得到一个 Empty Application 工程的方法: ...

  6. POJ 1155 树形背包(DP) TELE

    题目链接:  POJ 1155 TELE 分析:  用dp[i][j]表示在结点i下最j个用户公司的收益, 做为背包处理.        dp[cnt][i+j] = max( dp[cnt][i+j ...

  7. JavaScript 目标装配式编程(Target Assemble Programming)

    TAP概述 脚本中一切皆对象,若还以传统模式思考编程模式,那简直是对不起脚本解释器的强大支持:我们应该以最接近人类操作方式的来表达人的意图. 更接近工作实践的方式,比如游戏中,一个人物一个角色,人物的 ...

  8. Thinkphp 表单验证

    在服务器端通过tp框架实现表单验证 用户名.密码.重复密码.邮箱.qq.手机号码.爱好.学历 具体步骤: 制作表单 表单form数据通过create()方法收集(验证功能要求我们必须通过create( ...

  9. Foreign Exchange(交换生换位置)

     Foreign Exchange Your non-profit organization (iCORE - international Confederation of Revolver Enth ...

  10. lua curl动态链接库编译安装(二)

    下面再介绍一下lua-curl中的lua-curl-0.2.tar.gz版本的安装方法,可能对于一般的人来说这个很简单,但是对于我们这些菜鸟来说就不一样了: # wget http://files.l ...