您的位置:首页 > 移动开发 > Android开发

Android解析相同接口返回不同格式json数据的方法

2018-08-02 14:52 921 查看

背景原因

目前由双牛掌柜为主导框架开发的一系列产品中,网络请求框架请求到的数据是默认解析成Model类的。即项目中不会手动去解析网络请求到的json数据。在项目中,使用封装好的框架自动解析成Model类。而且Model类使用JsonFormat工具生成,所以在项目的开发中,不会或者说是减少了由于手误而打错了字段问题。

项目对网络处理的繁琐过程进行了高度封装。但是封装的框架是基于后台数据格式不会改变的情况,一旦后天返回的数据产生了变化,网络解析就会发生错误。

问题产生位置

所有设计到微信和支付宝两种支付方式共存的地方。

分析

当请求接口时支付宝返回的json如下(隐私数据已隐藏):

{
"status": 1,
"msg": "支付宝支付所需数据",
"result": "**************此处时吊起支付宝的数据,不做展示****************"
}

微信返回的json数据如下(隐私数据已隐藏):

{
"status": 1,
"msg": "微信支付所需数据",
"result": {
"appid": "************",
"partnerid": "************",
"prepayid": "************",
"package": "Sign=WXPay",
"noncestr": "************",
"timestamp": 1532915535,
"sign": "************"
}
}

调起微信或支付宝的数据位于result字段的数据中。根据上面两种不同的格式,清楚的发现这是两种不同的格式,一个是字符串,一个是键值对对象。这种情况在双牛掌柜网络请求框架中目前是不存在解析方式的。所以要给出一种简便可复用的解决方案。

解决方案

双牛掌柜框架中,支付流程过程高度封装,对于不同的项目只需修改微信的appid。即使涉及到逻辑变动,支付流程变动也不会很大,或者压根不会变动。

1.双牛掌柜支付流程如下(余额支付没举例,但是已封装)

双牛掌柜支付过程.png

在项目实际使用的过程中,只需复写网络请求获取信息,和回调支付这两个地方,因为不同的支付位置会使用不同的支付接口,接口会变。其他的地方不会发生变化。

解决方案一

接口返回不同数据这个问题很早就出现了,当时由于项目紧张,采取了一个接口根据返回数据的不同,分成了两个接口;在进行逻辑处理的时候,手动判断调用对应的接口。但是这种实现的方式过于繁琐,所有的逻辑过程都要考虑清楚,代码编写的过程中不停的造轮子。

写两套接口,意味着如流程图所示的流程会走两遍,加大了代码的复杂度。

此处不做代码展示。

解决方案二

第二种方式的核心思想是代码解耦合。由于之前网络请求框架高度封装,所以整体上是高内聚低耦合,但是如果想对网络请求框架进行自定义,又必须姐耦合,这就是编程中的矛盾点。

1.手动解析json数据,让框架不在解析。

此处操作乍一看挺复杂,但是实际操作的过程中并不是很复杂。将接口返回数据的泛型替换成ResponseBody就可以获取到未解析的数据了。代码如下:

/**
* 我要买单
*
* @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
);

当请求到数据时,把数据转成String格式,就可以对数据记性拆箱操作了。代码如下:

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

至此问题已解决。

总结

代码高度封装带来编程的便利,但是对于一些变数也会产生一些难以解决的问题。这就需要在代码编写之前就要对整理进行一个分析,分析一定要全面,而且代码一定要可扩展,不能写死,不能让某种变数导致框架不能使用。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

您可能感兴趣的文章:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息