Android解析相同接口返回不同格式json数据的方法
背景原因
目前由双牛掌柜为主导框架开发的一系列产品中,网络请求框架请求到的数据是默认解析成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); } }
至此问题已解决。
总结
代码高度封装带来编程的便利,但是对于一些变数也会产生一些难以解决的问题。这就需要在代码编写之前就要对整理进行一个分析,分析一定要全面,而且代码一定要可扩展,不能写死,不能让某种变数导致框架不能使用。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。