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. JavaScript回调函数的理解

    这里是个人对回调函数的一段理解 <!DOCTYPE html> <html> <head> <title>回调函数</title> < ...

  2. Ci 自己的分页类【原创】

    这里是自己手写的一个CI分页类的实现 <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); /** ...

  3. Android LayoutInflater和findViewById 源码详解

    LayoutInflater大家很熟悉,简单点说就是布局文件XML解析器,setContentView函数也是调用了LayoutInflater 用法: View view = LayoutInfla ...

  4. [转] 与调试器共舞 - LLDB 的华尔兹

    你是否曾经苦恼于理解你的代码,而去尝试打印一个变量的值? NSLog(@"%@", whatIsInsideThisThing); 或者跳过一个函数调用来简化程序的行为? NSNu ...

  5. javascript入门学习笔记

    <button type="button" onclick="alert('Welcome!')">点击这里</button>alert ...

  6. PHP面向对象(OOP)编程完全教程:10.__set(),__get(),__isset(),__unset()四个方法的应用

    一般来说,总是把类的属性定义为private,这更符合现实的逻辑.但是, 对属性的读取和赋值操作是非常频繁的,因此在PHP5中,预定义了两个函数”__get()”和”__set()”来获取和赋值其属性 ...

  7. 转:如何创建.htaccess文件

    方法1.开始-运行-键入cmd,打开cmd窗口 此时的cmd窗口路径是C:\Documents and Settings\username> 键入以下(不包括括号内信息): copy con . ...

  8. linq 的Distinct 扩展方法.

    List<miniclass> classs = new List<miniclass>(); classs.Add(new miniclass() { token = &qu ...

  9. Growing Pains for Deep Learning

    Growing Pains for Deep Learning Advances in theory and computer hardware have allowed neural network ...

  10. C51指针的使用

    指针就是指变量或数据所在的存储区地址.如一个字符型的变量 STR 存放在内存单元DATA 区的 51H 这个地址中,那么 DATA 区的 51H 地址就是变量 STR 的指针.在 C 语言中指针是一个 ...