Volley 百财帮封装

时间:2023-03-09 17:33:24
Volley 百财帮封装

Activity

Volley 百财帮封装
public class MainActivity extends Activity implements OnClickListener {
    private Context ctx;
    private TextView tv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ctx = this;
        setContentView(R.layout.activity_main);
        findViewById(R.id.button1).setOnClickListener(this);
        findViewById(R.id.button2).setOnClickListener(this);
        findViewById(R.id.button3).setOnClickListener(this);
        findViewById(R.id.button4).setOnClickListener(this);
        tv = (TextView) findViewById(R.id.tv);
    }
    @Override
    public void onClick(View v) {
        tv.setText("");
        switch (v.getId()) {
        case R.id.button1:
            requestLogin();
            break;
        case R.id.button2:
            requestUserDetailInfo();
            break;
        case R.id.button3:
            requestUserWallet();
            break;
        case R.id.button4:
            requestUserBankCard();
            break;
        default:
            break;
        }
    }
    /**
     * 登录
     */
    private void requestLogin() {
        JSONObject obj = new JSONObject();
        try {
            obj.put("Mobile", "13412341234");
            obj.put("Password", "12341234");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        BcbJsonRequest jsonRequest = new BcbJsonRequest(Urls.UserDoLogin, obj, null, new BcbRequest.BcbCallBack<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                Log.i("bqt", "登录后返回的数据:" + response.toString());
                if (HttpCallBackUtils.getRequestStatus(response, ctx)) {
                    JSONObject data = HttpCallBackUtils.getResultObject(response);
                    if (data != null) {
                        App.instance.setAccessToken(data.optString("Access_Token"));
                        tv.setText(JsonFormatTool.formatJson(data.toString()));
                    }
                }
            }
            @Override
            public void onErrorResponse(Exception error) {
            }
        });
        App.instance.getRequestQueue().add(jsonRequest);
    }
    /**
     * 用户信息
     */
    private void requestUserDetailInfo() {
        BcbJsonRequest jsonRequest = new BcbJsonRequest(Urls.UserMessage, null, App.instance.getAccessToken(), new BcbRequest.BcbCallBack<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                Log.i("bqt", "用户信息:" + response.toString());
                if (HttpCallBackUtils.getRequestStatus(response, ctx)) {
                    JSONObject data = HttpCallBackUtils.getResultObject(response);
                    if (data != null) {
                        tv.setText(JsonFormatTool.formatJson(data.toString()));
                    }
                }
            }
            @Override
            public void onErrorResponse(Exception error) {
            }
        });
        App.instance.getRequestQueue().add(jsonRequest);
    }
    /**
     * 用户钱包
     */
    private void requestUserWallet() {
        BcbJsonRequest jsonRequest = new BcbJsonRequest(Urls.UserWallet, null, App.instance.getAccessToken(), new BcbRequest.BcbCallBack<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                Log.i("bqt", "用户钱包:" + response.toString());
                if (HttpCallBackUtils.getRequestStatus(response, ctx)) {
                    JSONObject data = HttpCallBackUtils.getResultObject(response);
                    if (data != null) {
                        tv.setText(JsonFormatTool.formatJson(data.toString()));
                    }
                }
            }
            @Override
            public void onErrorResponse(Exception error) {
            }
        });
        App.instance.getRequestQueue().add(jsonRequest);
    }
    /**
     * 用户银行卡
     */
    private void requestUserBankCard() {
        BcbJsonRequest jsonRequest = new BcbJsonRequest(Urls.UrlUserBand, null, App.instance.getAccessToken(), new BcbRequest.BcbCallBack<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                Log.i("bqt", "用户银行卡:" + response.toString());
                if (HttpCallBackUtils.getRequestStatus(response, ctx)) {
                    JSONObject data = HttpCallBackUtils.getResultObject(response);
                    if (data != null) {
                        tv.setText(JsonFormatTool.formatJson(data.toString()));
                    }
                }
            }
            @Override
            public void onErrorResponse(Exception error) {
            }
        });
        App.instance.getRequestQueue().add(jsonRequest);
    }
}

全局Application
public class App extends Application {
    public static App instance;
    private RequestQueue requestQueue;
    private String accessToken;
    @Override
    public void onCreate() {
        super.onCreate();
        instance = this;
    }
    public RequestQueue getRequestQueue() {
        if (null == requestQueue) requestQueue = Volley.newRequestQueue(this);
        return requestQueue;
    }
    public String getAccessToken() {
        return accessToken;
    }
    public void setAccessToken(String accessToken) {
        this.accessToken = accessToken;
    }
}

加密解密工具
public class DESUtil {
    /**
     * 从加密了的token中获取key
     */
    public static String decodeKey(String encodeToken) {
        try {
            byte[] baseDecodeResult = Base64.decode(encodeToken, Base64.DEFAULT);
            byte[] keybyte = MyConstants.KEY.getBytes();
            byte[] decodeByte_ECB = ees3DecodeECB(keybyte, baseDecodeResult);
            String decodeString_ECB = new String(decodeByte_ECB, "UTF-8");
            // 从已加密的token中解析key
            // 先解密token为铭文,再解析字符串        {usertoken}|{secutiryKey}
            if (null != decodeString_ECB && decodeString_ECB.contains("|")) return decodeString_ECB.substring(decodeString_ECB.indexOf("|") + 1);
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 加密数据
     */
    @SuppressLint("TrulyRandom")
    public static byte[] des3EncodeECB(byte[] key, byte[] data) throws Exception {
        DESedeKeySpec spec = new DESedeKeySpec(key);
        SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
        Key deskey = keyfactory.generateSecret(spec);
        Cipher cipher = Cipher.getInstance("desede" + "/ECB/PKCS7Padding");
        cipher.init(Cipher.ENCRYPT_MODE, deskey);
        byte[] bOut = cipher.doFinal(data);
        return bOut;
    }
    /**
     * 解密数据
     */
    public static byte[] ees3DecodeECB(byte[] key, byte[] data) throws Exception {
        DESedeKeySpec spec = new DESedeKeySpec(key);
        SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
        Key deskey = keyfactory.generateSecret(spec);
        Cipher cipher = Cipher.getInstance("desede" + "/ECB/PKCS7Padding");
        cipher.init(Cipher.DECRYPT_MODE, deskey);
        byte[] bOut = cipher.doFinal(data);
        return bOut;
    }
}

请求Request
public abstract class BcbRequest<T> extends Request<T> {
    protected static final String PROTOCOL_CHARSET = "utf-8";
    protected static final String CONTENT_TYPE = "application/json; charset=utf-8";
    //自定义监听器
    private BcbCallBack<T> mBcbCallBack;
    private BcbIndexCallBack<T> mBcbIndexCallBack;
    //Post请求的实体,如果为 null,则为GET请求,否则为POST请求
    private String mRequestBody;
    //已加密的token,没有为null
    private String mEncodeToken;
    private String key;
    //位置参数,默认为 -1,表示不使用位置参数回调
    private int index = -1;
    //是否添加设备信息
    private boolean isAddDevInfo = true;
    //************************************************        重写请求头,请求头是不用加密的        ******************************************
    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        Map<String, String> headers = new HashMap<String, String>();
        try {
            if (mEncodeToken != null) headers.put("access-token", mEncodeToken);
            String pkName = App.instance.getPackageName();//包名
            String version = App.instance.getPackageManager().getPackageInfo(pkName, 0).versionName;//清单文件中设置的版本号
            headers.put("version", version);
            headers.put("platform", "2");
            Log.i("bqt", "【请求头】" + headers.toString());
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return headers;
    }
    //************************************************        重写请求体,请求体中的数据都是加密的        ******************************************
    /**
     * 重写请求实体
     * @return 如果存在请求的参数,则需要返回加了密的请求实体
     */
    @Override
    public byte[] getBody() {
        try {
            // 检测传入的密文token是否为空,没有token参数,数据解密的key为默认的
            if (null == mEncodeToken) {
                Log.i("bqt", "【加密前的请求体】" + mRequestBody);
                key = MyConstants.KEY;
            } else key = DESUtil.decodeKey(mEncodeToken);
            // 如果传入参数不为空,则需要加密传入的数据
            if (null != mRequestBody) {
                byte[] data = mRequestBody.getBytes(PROTOCOL_CHARSET);
                byte[] encodeByte_ECB = DESUtil.des3EncodeECB(key.getBytes(), data);
                String body = Base64.encodeToString(encodeByte_ECB, Base64.DEFAULT);
                Log.i("bqt", "【加密后的请求体】" + body.toString());
                return body.getBytes();
            }
        } catch (Exception e) {
            VolleyLog.wtf("Unsupported DES3Encoding while trying to get the bytes of %s using %s", mRequestBody, PROTOCOL_CHARSET);
        }
        //返回为空
        return null;
    }
    //************************************************        构造函数        ******************************************
    /**
     * 构造函数
     * @param url         请求地址
     * @param requestBody 请求实体
     * @param encodeToken 已加密的token,没有就传null
     * @param bcbCallBack 请求结果回调
     */
    public BcbRequest(String url, String requestBody, String encodeToken, BcbCallBack<T> bcbCallBack) {
        this(requestBody == null ? Method.GET : Method.POST, url, requestBody, encodeToken, bcbCallBack);
    }
    /**
     * 构造函数
     * @param method      请求方式
     * @param url         请求地址
     * @param requestBody 请求实体
     * @param encodeToken 已加密的token,没有就传null
     * @param bcbCallBack 请求结果回调
     */
    public BcbRequest(int method, String url, String requestBody, String encodeToken, final BcbCallBack bcbCallBack) {
        //将出错信息用接口保存起来
        super(method, url, new ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                bcbCallBack.onErrorResponse(error);
            }
        });
        Log.i("url", "url = " + url + " requestBody = " + requestBody);
        mBcbCallBack = bcbCallBack;
        if (TextUtils.isEmpty(requestBody)) mRequestBody = null;
        else mRequestBody = requestBody;
        mEncodeToken = encodeToken;
    }
    /**
     * 构造函数
     * @param method       请求方式
     * @param url          请求接口
     * @param requestBody  请求实体
     * @param encodeToken  已加密的token,没有就传null
     * @param isAddDevInfo 是否添加设备信息
     * @param bcbCallBack  请求结果回调
     */
    public BcbRequest(int method, String url, String requestBody, String encodeToken, boolean isAddDevInfo, final BcbCallBack bcbCallBack) {
        //将出错信息用接口保存起来
        super(method, url, new ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                bcbCallBack.onErrorResponse(error);
                Log.d("url", "error = " + error.toString());
            }
        });
        Log.d("url", "url = " + url + " requestBody = " + requestBody);
        mBcbCallBack = bcbCallBack;
        if (TextUtils.isEmpty(requestBody)) mRequestBody = null;
        else mRequestBody = requestBody;
        mEncodeToken = encodeToken;
        this.isAddDevInfo = isAddDevInfo;
    }
    /**
     * 构造函数
     * @param method      请求方式
     * @param url         请求接口
     * @param requestBody 请求实体,没有就传null
     * @param encodeToken 已加密的token, 没有就传null
     * @param index       位置参数,主要用于记录列表某个位置请求
     * @param bcbCallBack 回调
     */
    public BcbRequest(int method, String url, String requestBody, String encodeToken, int index, final BcbIndexCallBack bcbCallBack) {
        //将出错信息用接口保存起来
        super(method, url, new ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                bcbCallBack.onErrorResponse(error);
            }
        });
        Log.i("bqt", "【url 】 " + url + " 【requestBody 】 " + requestBody);
        this.index = index;
        mBcbIndexCallBack = bcbCallBack;
        if (TextUtils.isEmpty(requestBody)) mRequestBody = null;
        else mRequestBody = requestBody;
        mEncodeToken = encodeToken;
    }
    //*********************************************        复写的函数        *********************************************
    @Override
    protected void deliverResponse(T response) {
        //如果不存在位置参数,则使用默认回调,否则使用位置回调
        if (index == -1) mBcbCallBack.onResponse(response);
        else mBcbIndexCallBack.onResponse(response, index);
    }
    /**
     * 子类必须实现该功能,对返回的回调响应数据 response.data 进行解码转成相应类型的数据
     */
    @Override
    abstract protected Response<T> parseNetworkResponse(NetworkResponse response);
    /**
     * @deprecated Use {@link #getBodyContentType()}.
     */
    @Override
    public String getPostBodyContentType() {
        return getBodyContentType();
    }
    /**
     * @deprecated Use {@link #getBody()}.
     */
    @Override
    public byte[] getPostBody() {
        return getBody();
    }
    @Override
    public String getBodyContentType() {
        return CONTENT_TYPE;
    }
    //************************************************        回调        ******************************************
    public interface BcbCallBack<T> {
        void onResponse(T response);
        void onErrorResponse(Exception error);
    }
    public interface BcbIndexCallBack<T> {
        void onResponse(T response, int index);
        void onErrorResponse(Exception error);
    }
}

请求封装Request
public class BcbJsonRequest extends BcbRequest<JSONObject> {
    private String mEncodeToken;
    /**
     * 服务器回调
     */
    @Override
    protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
        try {
            //返回不成功,则提示是否成功
            if (response.statusCode != 200) {
                Log.i("bqt", "返回出错,状态码为:" + response.statusCode + " 请求链接:" + getUrl());
                return Response.error(new ParseError());
            }
            //获取解密的key,没有token参数,数据解密的key为默认的
            String key;
            if (null == mEncodeToken) key = MyConstants.KEY;
            else key = DESUtil.decodeKey(mEncodeToken);
            Log.i("bqt", "【加密的Token】" + mEncodeToken);
            Log.i("bqt", "【解密的Token】" + key);
            //解密数据
            String result = new String(response.data);
            byte[] baseDecodeResult = Base64.decode(result, Base64.DEFAULT);
            byte[] keybyte = key.getBytes();
            byte[] decodeByte_ECB = DESUtil.ees3DecodeECB(keybyte, baseDecodeResult);
            String decodeJsonString = new String(decodeByte_ECB, PROTOCOL_CHARSET);
            Log.i("bqt", "【加密的JSON串】" + result);
            Log.i("bqt", "【解密的JSON串】" + decodeJsonString);
            //返回解密后的对象
            return Response.success(new JSONObject(decodeJsonString), HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JSONException je) {
            return Response.error(new ParseError(je));
        } catch (Exception ex) {
            return Response.error(new ParseError(ex));
        }
    }
    //*********************************************            构造函数            *********************************************
    /**
     * 构造函数,默认为POST请求
     * @param url           请求接口
     * @param jsonObject    JSONObject对象
     * @param encodeToken   Token
     * @param callBack      请求回调
     */
    public BcbJsonRequest(String url, JSONObject jsonObject, String encodeToken, BcbCallBack<JSONObject> callBack) {
        this(Method.POST, url, jsonObject, encodeToken, callBack);
    }
    /**
     * 构造函数,默认为POST请求
     * @param url           请求接口
     * @param jsonObject    JSONObject对象
     * @param encodeToken   Token
     * @param index         位置参数
     * @param callBack      请求回调
     */
    public BcbJsonRequest(String url, JSONObject jsonObject, String encodeToken, int index, BcbIndexCallBack<JSONObject> callBack) {
        this(Method.POST, url, jsonObject, encodeToken, index, callBack);
    }
    /**
     * 构造函数
     * @param url           请求接口
     * @param jsonObject    JSONObject对象
     * @param encodeToken   Token
     * @param isAddDevInfo  是否添加设备信息
     * @param callBack      请求回调
     */
    public BcbJsonRequest(String url, JSONObject jsonObject, String encodeToken, boolean isAddDevInfo, BcbCallBack<JSONObject> callBack) {
        super(Method.POST, url, jsonObject == null ? "" : jsonObject.toString(), encodeToken, isAddDevInfo, callBack);
        mEncodeToken = encodeToken;
    }
    /**
     * 构造函数
     * @param method        请求方式,GET ? POST 还是其他
     * @param url           请求接口
     * @param jsonObject    JSONObject对象
     * @param encodeToken   Token
     * @param callBack      请求回调
     */
    public BcbJsonRequest(int method, String url, JSONObject jsonObject, String encodeToken, BcbCallBack<JSONObject> callBack) {
        super(method, url, jsonObject == null ? "" : jsonObject.toString(), encodeToken, callBack);
        mEncodeToken = encodeToken;
    }
    /**
     * 构造函数
     * @param method        请求方式,GET ? POST 还是其他
     * @param url           请求接口
     * @param jsonObject    JSONObject对象
     * @param encodeToken   Token
     * @param index         位置参数
     * @param callBack      请求回调
     */
    public BcbJsonRequest(int method, String url, JSONObject jsonObject, String encodeToken, int index, BcbIndexCallBack<JSONObject> callBack) {
        super(method, url, jsonObject == null ? "" : jsonObject.toString(), encodeToken, index, callBack);
        mEncodeToken = encodeToken;
    }
}