Android解析相同接口返回不同格式json數(shù)據(jù)的方法
背景原因
目前由雙牛掌柜為主導框架開發(fā)的一系列產品中,網(wǎng)絡請求框架請求到的數(shù)據(jù)是默認解析成Model類的。即項目中不會手動去解析網(wǎng)絡請求到的json數(shù)據(jù)。在項目中,使用封裝好的框架自動解析成Model類。而且Model類使用JsonFormat工具生成,所以在項目的開發(fā)中,不會或者說是減少了由于手誤而打錯了字段問題。
項目對網(wǎng)絡處理的繁瑣過程進行了高度封裝。但是封裝的框架是基于后臺數(shù)據(jù)格式不會改變的情況,一旦后天返回的數(shù)據(jù)產生了變化,網(wǎng)絡解析就會發(fā)生錯誤。
問題產生位置
所有設計到微信和支付寶兩種支付方式共存的地方。
分析
當請求接口時支付寶返回的json如下(隱私數(shù)據(jù)已隱藏):
{
"status": 1,
"msg": "支付寶支付所需數(shù)據(jù)",
"result": "**************此處時吊起支付寶的數(shù)據(jù),不做展示****************"
}
微信返回的json數(shù)據(jù)如下(隱私數(shù)據(jù)已隱藏):
{
"status": 1,
"msg": "微信支付所需數(shù)據(jù)",
"result": {
"appid": "************",
"partnerid": "************",
"prepayid": "************",
"package": "Sign=WXPay",
"noncestr": "************",
"timestamp": 1532915535,
"sign": "************"
}
}
調起微信或支付寶的數(shù)據(jù)位于result字段的數(shù)據(jù)中。根據(jù)上面兩種不同的格式,清楚的發(fā)現(xiàn)這是兩種不同的格式,一個是字符串,一個是鍵值對對象。這種情況在雙牛掌柜網(wǎng)絡請求框架中目前是不存在解析方式的。所以要給出一種簡便可復用的解決方案。
解決方案
雙牛掌柜框架中,支付流程過程高度封裝,對于不同的項目只需修改微信的appid。即使涉及到邏輯變動,支付流程變動也不會很大,或者壓根不會變動。
1.雙牛掌柜支付流程如下(余額支付沒舉例,但是已封裝)

雙牛掌柜支付過程.png
在項目實際使用的過程中,只需復寫網(wǎng)絡請求獲取信息,和回調支付這兩個地方,因為不同的支付位置會使用不同的支付接口,接口會變。其他的地方不會發(fā)生變化。
解決方案一
接口返回不同數(shù)據(jù)這個問題很早就出現(xiàn)了,當時由于項目緊張,采取了一個接口根據(jù)返回數(shù)據(jù)的不同,分成了兩個接口;在進行邏輯處理的時候,手動判斷調用對應的接口。但是這種實現(xiàn)的方式過于繁瑣,所有的邏輯過程都要考慮清楚,代碼編寫的過程中不停的造輪子。
寫兩套接口,意味著如流程圖所示的流程會走兩遍,加大了代碼的復雜度。
此處不做代碼展示。
解決方案二
第二種方式的核心思想是代碼解耦合。由于之前網(wǎng)絡請求框架高度封裝,所以整體上是高內聚低耦合,但是如果想對網(wǎng)絡請求框架進行自定義,又必須姐耦合,這就是編程中的矛盾點。
1.手動解析json數(shù)據(jù),讓框架不在解析。
此處操作乍一看挺復雜,但是實際操作的過程中并不是很復雜。將接口返回數(shù)據(jù)的泛型替換成ResponseBody就可以獲取到未解析的數(shù)據(jù)了。代碼如下:
/**
* 我要買單
*
* @param payCode
* @param zflx 1掃碼買單 2附近商家我要買單 3商家報單 4充值 5升級 6商城消費
*/
@FormUrlEncoded
@POST("Near/wymd")
Observable<ResponseBody> wymd(
@Field("snzg_user_id") String userId,
@Field("shop_user_id") String shopUserId,
@Field("money") String money,
@Field("bd_id") String bdId,
@Field("pay_code") int payCode,
@Field("zflx") int zflx
);
當請求到數(shù)據(jù)時,把數(shù)據(jù)轉成String格式,就可以對數(shù)據(jù)記性拆箱操作了。代碼如下:
@Override
public void handleSuccess(Object result) {
toPay(result.toString(), wymd.getPaycode());
}
然后再使用Gson解析工具,將json轉換成對象。
protected void toPay(String payInfo, int payCode) {
//余額
if (payCode == 3) {
payEnd("支付成功");
}
//微信
if (payCode == 2) {
wxPayResult = GsonUtil.parseJsonWithGson(payInfo, WxPayResult.class);
weChatPay();
}
//支付寶
if (payCode == 1) {
alipay(payInfo);
}
}
至此問題已解決。
總結
代碼高度封裝帶來編程的便利,但是對于一些變數(shù)也會產生一些難以解決的問題。這就需要在代碼編寫之前就要對整理進行一個分析,分析一定要全面,而且代碼一定要可擴展,不能寫死,不能讓某種變數(shù)導致框架不能使用。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Android開發(fā)中ProgressDialog簡單用法示例
這篇文章主要介紹了Android開發(fā)中ProgressDialog簡單用法,結合實例形式分析了Android使用ProgressDialog的進度條顯示與關閉、更新等事件響應相關操作技巧,需要的朋友可以參考下2017-10-10
Android編程實現(xiàn)調用相冊、相機及拍照后直接裁剪的方法
這篇文章主要介紹了Android編程實現(xiàn)調用相冊、相機及拍照后直接裁剪的方法,涉及Android拍照及圖形處理相關操作技巧,需要的朋友可以參考下2017-02-02
Android Activity 與Service進行數(shù)據(jù)交互詳解
這篇文章主要介紹了Android Activity 與Service進行數(shù)據(jù)交互的相關資料,在開發(fā)Android App的時候經常會使用這樣的功能,需要的朋友可以參考下2016-10-10
Android實現(xiàn)帶有刪除按鈕的EditText示例代碼
本文給大家介紹一個很實用的小控件,就是在Android系統(tǒng)的輸入框右邊加入一個小圖標,點擊小圖標可以清除輸入框里面的內容,IOS上面直接設置某個屬性就可以實現(xiàn)這一功能,但是Android原生EditText不具備此功能,所以要想實現(xiàn)這一功能我們需要重寫EditText。下面來看看吧。2016-12-12

