并不是所有的接口都是按照常规的来的。
比如前段时间我公司接了一个三期的一个项目,项目内使用一个二封过的Volley。我想将自己的库移入来替代掉,但是发现这个项目使用的接口协议不太一样,我分析了一下做了个简单的二封。解决特殊协议的问题
首先有几个要点
- 使用soap协议
- 接口发送的是原始流数据
- xml格式发送和返回
1.协议就使用项目中的老代码已有的格式
soap协议具体是什么可以自行百度。现在我们仅关心如何发送和接收数据
这个项目已经写好了协议的其它项。cxf代表具体接口地址,requestParam是发送的参数。之后我们使用String.format(soap,cxf,requestParam,cxf);替换即可
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cxf="http://cxf.spring.core.sinosoft.com/"> <soapenv:Header/> <soapenv:Body> <cxf:%s> <requestParam>%s</requestParam> </cxf:%s> </soapenv:Body> </soapenv:Envelope>
2.使用继承复写发送网络请求前的方法来发送原始流数据
fastlib网络功能中有发送原始字节流的功能
Request.setByteStream(byte[]);
但是我们不直接使用,因为要发送的参数个具体接口要填充到协议中然后再转换成字节组发出去,所以使用继承来将这些重复的功能封一下
这样封装好后用起来和Request一样,还是原来的味道,还是一样的配方public class AppRequest extends Request{ public static final String URL ="https://xxx/xxxx?wsdl"; public static final String AOSPFORMAT = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" " + "xmlns:cxf=\"http://cxf.spring.core.sinosoft.com/\">\n"+ "<soapenv:Header/>\n" + "<soapenv:Body>\n" + "<cxf:%s>\n" + "<requestParam>%s</requestParam>\n" + "</cxf:%s>\n" + "</soapenv:Body>\n" + "</soapenv:Envelope>"; public String mMethod; public AppRequest(String method){ super("POST",URL); mMethod=method; } @Override public Request start(boolean forceRefresh) { Gson gson=new Gson(); String content=gson.toJson(getParams()); //参数是put进参数的本体 String realContent=String.format(AOSPFORMAT,mMethod,content,mMethod); setByteStream(realContent.getBytes()); //设置要发送的流数据 return super.start(forceRefresh); } }
3.xml的返回使用全局来进行解析
接口的数据返回也是xml格式的。我们仅取return中的数据即可
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:expenseListAccBankListResponse xmlns:ns2="http://cxf.spring.core.sinosoft.com/">
<return>{"success":"false","msg":"密匙不匹配!","serviceName":"expenseListAccBankList","obj":[]}</return>
</ns2:expenseListAccBankListResponse>
</soap:Body>
</soap:Envelope>
<soap:Body>
<ns2:expenseListAccBankListResponse xmlns:ns2="http://cxf.spring.core.sinosoft.com/">
<return>{"success":"false","msg":"密匙不匹配!","serviceName":"expenseListAccBankList","obj":[]}</return>
</ns2:expenseListAccBankListResponse>
</soap:Body>
</soap:Envelope>
使用全局返回监听.即所有网络请求返回都会过一遍这个监听并且可以改变返回的数据,那么我们只要把return中的数据拆出来即可
NetManager.getInstance().setGlobalListener(new GlobalListener(){ @Override public String onTranslateJson(Request r, String json){ String contentStr=null; try { contentStr=parseSoapXml(); } catch (XmlPullParserException | IOException e) { e.printStackTrace(); } if(contentStr==null) onErrorListener(r,"解析xml失败"); return contentStr; } });
自此,可以按照约定的协议来使用fastlib的网络功能了
AppRequest request=new AppRequest("getBankCardList"); request.put("userId","1234"); request.setListener(new SimpleListener<ResponseBean<BankCard>>(){ @Override public void onResponseListener(Request r, ResponseBean<BankCard> result){ System.out.println(result); } }); net(request);