调用中行接口针对返回报文(xml形式)做相关处理
2018-01-26 11:45
369 查看
最近在对接中行银行接口,在获取返回报文的时候遇到一些问题,现在在这里做个总结
TIP:
在返回报文之前,要对前置机的URL请求,在这期间遇到一个坑,还是通过查看日志才发现问题
在填写转账信息的时候要求输入转账公司名称,但是银行接口又不会强制对转账公司名称校验,而且转账操作也会显示成功,只是在查询交易状态的时候才会显示
交易失败被银行退回/收款人账号和收款人名称不一致的错误
当时有点懵逼,还仔细检查到底有没有输错信息 = =
后来使用Postman把我要发送的报文粘贴进去,发现成功!这时候才发现是编码问题
原来
最开始使用下面方法设置字符集
发现这样不会把字符设置为UTF-8的编码,所以系统就取了默认的编码格式
原来是要在转换为字节数组的时候给它设置字符编码
1.普通报文
上面是调用银行接口成功签到的报文,类似于这样的特征就比较明显,不需要做任何处理,就能通过下面Dom4j提供的基础方法对每个节点进行操作
上面方法就已经获取到返回报文的根节点了,这个时候你就能获取到任何你想要的节点参数了
例如:
获取b2e0001-rs节点下面status的值
想要获取其他节点值也与上面方法一样
2.报文中含有规律重复节点处理
例如接口中的历史余额查询返回的报文
上面返回的报文中就有多个b2e0012-rs节点,这种情况就不能像上面简单的去获取,要特殊处理
1.使用递归去遍历每个节点,在遍历到b2e0012-rs时候,操作就和普通的一样
2.上面的historyBalanceBanks是定义了一个全局静态变量
在调用递归方法之后将historyBalanceBanks塞入到返回的实体类中,大功告成
TIP:
在返回报文之前,要对前置机的URL请求,在这期间遇到一个坑,还是通过查看日志才发现问题
在填写转账信息的时候要求输入转账公司名称,但是银行接口又不会强制对转账公司名称校验,而且转账操作也会显示成功,只是在查询交易状态的时候才会显示
交易失败被银行退回/收款人账号和收款人名称不一致的错误
当时有点懵逼,还仔细检查到底有没有输错信息 = =
后来使用Postman把我要发送的报文粘贴进去,发现成功!这时候才发现是编码问题
原来
最开始使用下面方法设置字符集
// 设置文件字符集: conn.setRequestProperty("Charset", "UTF-8");
发现这样不会把字符设置为UTF-8的编码,所以系统就取了默认的编码格式
原来是要在转换为字节数组的时候给它设置字符编码
//转换为字节数组 byte[] data = xml.getBytes("UTF-8");
1.普通报文
<?xml version="1.0" encoding="UTF-8"?> <bocb2e version="120" locale="zh_CN"> <head> <termid>E192168000105</termid> <trnid>20060704001</trnid> <custid>133724203</custid> <cusopr>135989127</cusopr> <trncod>b2e0001</trncod> <token>SyX3PnpuNdIQm6FDj1SgZn8</token> </head> <trans> <trn-b2e0001-rs> <status> <rspcod>B001</rspcod> <rspmsg>ok</rspmsg> </status> <serverdt>20180126105944</serverdt> <token>SyX3PnpuNdIQm6FDj1SgZn8</token> </trn-b2e0001-rs> </trans> </bocb2e>
上面是调用银行接口成功签到的报文,类似于这样的特征就比较明显,不需要做任何处理,就能通过下面Dom4j提供的基础方法对每个节点进行操作
Document document = DocumentHelper.parseText("传入的报文"); //获取文档根节点 Element root = document.getRootElement();
上面方法就已经获取到返回报文的根节点了,这个时候你就能获取到任何你想要的节点参数了
例如:
获取b2e0001-rs节点下面status的值
Element rspcodElem = root.element("trans").element("trn-b2e0001-rs").element("status") .element("rspcod"); rspcodElem.getStringValue()//节点的值 rspcodElem.getName()//节点名称
想要获取其他节点值也与上面方法一样
2.报文中含有规律重复节点处理
例如接口中的历史余额查询返回的报文
<?xml version="1.0" encoding="UTF-8"?> <bocb2e version="120" locale="zh_CN"> <head> <termid>E192168000105</termid> <trnid>04051003128</trnid> <custid>133724203</custid> <cusopr>135989127</cusopr> <trncod>b2e0012</trncod> <token>PCxkDXIhAPRtlBhuqF-6A-V</token> </head> <trans> <trn-b2e0012-rs> <status> <rspcod>B001</rspcod> <rspmsg>ok</rspmsg> </status> <b2e0012-rs> <status> <rspcod>B001</rspcod> <rspmsg>ok</rspmsg> </status> <account> <ibknum>47504</ibknum> <actacn>726357720234</actacn> <curcde>CNY</curcde> </account> <balance> <bokbal>199799896.54</bokbal> <avabal>199799871.54</avabal> </balance> <baldat>20180102</baldat> </b2e0012-rs> <b2e0012-rs> <status> <rspcod>B001</rspcod> <rspmsg>ok</rspmsg> </status> <account> <ibknum>47504</ibknum> <actacn>726357720234</actacn> <curcde>CNY</curcde> </account> <balance> <bokbal>199799871.54</bokbal> <avabal>199799871.54</avabal> </balance> <baldat>20180103</baldat> </b2e0012-rs> </trn-b2e0012-rs> </trans> </bocb2e>
上面返回的报文中就有多个b2e0012-rs节点,这种情况就不能像上面简单的去获取,要特殊处理
1.使用递归去遍历每个节点,在遍历到b2e0012-rs时候,操作就和普通的一样
private static void getHistoryBalanceChildNodes(Element elem){ HistoryBalanceBank historyBalanceBank=new HistoryBalanceBank(); if (("b2e0012-rs").equals(elem.getName())){ historyBalanceBank.setRspcod(elem.element("status").element("rspcod").getStringValue()); historyBalanceBank.setRspmsg(elem.element("status").element("rspmsg").getStringValue()); if (("B001").equals(elem.element("status").element("rspcod").getStringValue())){ historyBalanceBank.setIbknum(elem.element("account").element("ibknum").getStringValue()); historyBalanceBank.setActacn(elem.element("account").element("actacn").getStringValue()); historyBalanceBank.setCurcde(elem.element("account").element("curcde").getStringValue()); historyBalanceBank.setBokbal(elem.element("balance").element("bokbal").getStringValue()); historyBalanceBank.setAvabal(elem.element("balance").element("avabal").getStringValue()); historyBalanceBank.setBaldat(elem.element("baldat").getStringValue()); } historyBalanceBanks.add(historyBalanceBank); } Iterator<Node> it= elem.nodeIterator(); while (it.hasNext()){ Node node = it.next(); if (node instanceof Element){ Element e1 = (Element)node; getHistoryBalanceChildNodes(e1); } } }
2.上面的historyBalanceBanks是定义了一个全局静态变量
//历史余额List private static List<HistoryBalanceBank> historyBalanceBanks=new ArrayList<HistoryBalanceBank>();
在调用递归方法之后将historyBalanceBanks塞入到返回的实体类中,大功告成
相关文章推荐
- HttpClient以json形式的参数调用http接口并对返回的json数据进行处理(可以带文件)
- HttpClient以json形式的参数调用http接口并对返回的json数据进行处理(可以带文件)
- 接口访问和返回的XML数据处理
- asp通过json调用webservice接口,并获取返回的xml数据及解析
- 如何调用并解析调用远程接口返回的xml数据
- JQuery调用webservice,返回的json数据和XML数据的处理方法
- SpringMvc返回报文形式的控制-验证方法: JSON or HTML or XML
- 异步调用接口返回大量数据,如何处理才能使页面渲染时不卡?
- PHP调用跨域接口,处理返回值JSON与XML
- web api写api接口时默认返回的是把你的对象序列化后以XML形式返回,那么怎样才能让其返回为json呢
- 电商系统如何调用支付宝接口代码,以及支付宝如何返回处理结果。
- 处理xml返回报文
- SoapUI 调用 CXF的restful形式接口服务异常:com.fasterxml.jackson.core.JsonParseException: Invalid UTF-8 start byt
- JQuery调用webservice,返回的json数据和XML数据的处理方法
- Java API接口调用,返回json格式处理
- POST形式 soapUI调用WebService的restful接口,传入json参数,并且返回json
- 调用接口,解析返回的的string类型xml文档
- 通过esb报文调用接口,返回报文数据
- 通过esb报文调用接口,返回报文数据
- php 调用接口的post方法,还有解析返回的xml数据