-
关于Webservice接口对接相关总结
因为近期处理了很多关于Webservice的接口对接,所以这篇文章是对近期自己的学习做一个简单的总结。
一:
对于接口对接,建议首先需要了解一下WSDL文件,以及入参的SOAP报文的阅读,各节点的含义。有时候对接的开发直接扔给你一个wsdl服务文件,或者一串soap报文让你调用,这种情况下,如果不了解如何阅读该文件包括相关节点的含义,就会很尴尬;其次,需要问清楚接口提供方,对方的接口有没有访问认证等,如果没有,可以采用自动生成客户端的形式处理,这种方式不再赘述,网上有一大堆的资料。我这里介绍一下我遇到的需要接口认证的方式,废话少说直接看代码:
//直接AXIS调用
public class WebserviceUtil { public static String getResult(ServiceInfoDto serviceInfoDto, String jsoninfo) throws ServiceException, MalformedURLException, RemoteException, SOAPException { //调用接口//标识Web Service的具体路径 String endpoint = serviceInfoDto.getEndpoint(); String namespace = serviceInfoDto.getNamespace(); String soapaction = serviceInfoDto.getSoapaction(); String username = new String("***"); String password = new String("***"); String HU_SENDR = new String("***"); String HU_JSON = jsoninfo; String result = ""; try { // 创建 Service实例 Service service = new Service(); QName qname = new QName(namespace, serviceInfoDto.getLocalPart()); // 通过Service实例创建Call的实例 Call call = (Call) service.createCall(); //为Call设置服务的位置 call.setTargetEndpointAddress(endpoint); call.setOperationName(qname); call.setEncodingStyle("UTF-8"); call.setSOAPActionURI(soapaction); call.setUsername(username); call.setPassword(password); call.addParameter(new QName("HU_JSON"), org.apache.axis.encoding.XMLType.XSD_STRING, javax.xml.rpc.ParameterMode.IN); call.addParameter(new QName("HU_SENDR"), org.apache.axis.encoding.XMLType.XSD_STRING, javax.xml.rpc.ParameterMode.IN); call.setReturnType(XMLType.XSD_STRING); // 返回值类型:String Object[] obj = {HU_JSON, HU_SENDR}; result = (String) call.invoke(obj);// 远程调用 // System.out.println("result is " + result); } catch (Exception e) { e.printStackTrace(); } return result; } }
public class ServiceInfoDto { private String endpoint; private String namespace; private String soapaction; private String localPart; public String getEndpoint() { return endpoint; } public void setEndpoint(String endpoint) { this.endpoint = endpoint; } public String getNamespace() { return namespace; } public void setNamespace(String namespace) { this.namespace = namespace; } public String getSoapaction() { return soapaction; } public void setSoapaction(String soapaction) { this.soapaction = soapaction; } public String getLocalPart() { return localPart; } public void setLocalPart(String localPart) { this.localPart = localPart; } }
1
2
3
4
5
6
7
|
解读一下入参和几个重要的参数: ServiceInfoDto对象:是对相关节点入参的汇总,这里的endpoint,namespace,soapaction,localPart在对方提供的wsdl文件中都可查到; jsoninfo:接口方要求的入参对象(转成json字符串形式入参) String username = new String( "***" ); 接口方提供的认证登录名(不需要可忽略) String password = new String( "***" ); 接口方提供的认证登录密码(不需要可忽略) String HU_SENDR = new String( "***" ); HU_SENDR需要按对方要求的字段名称处理,入参值接口方提供(不需要可忽略); String HU_JSON = jsoninfo;HU_JSON;需要按对方要求的字段名称处理,入参值是前面处理过的json对象; |
二:
第二种对接是拼接SOAP报文入参,并且解析返回的SOAP报文,获取返回信息; 这种方式必须要清楚的知道对方入参的soap报文格式,相关节点一定要清晰,拿到对方的报文信息进行拼接即可: soap报文拼接,由于我用到的地方比较多,所以提取的代码块处理
public class SoapAppendXml { public static StringBuffer soapXml(String arg2,String arg4,String method,String id) { StringBuffer sendSoapString = new StringBuffer(); sendSoapString.append("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:web=\"http://webservice.**.com/\">"); sendSoapString.append(" <soapenv:Header/>"); sendSoapString.append(" <soapenv:Body>"); sendSoapString.append(" <web:"+method+">"); sendSoapString.append(" <arg0>*</arg0>"); sendSoapString.append(" <arg1>false</arg1>"); sendSoapString.append(" <arg2>"+arg2+"</arg2>"); sendSoapString.append(" <arg3>[]</arg3>"); sendSoapString.append(" <arg4>"+arg4+"</arg4>"); sendSoapString.append(" </web:"+method+">"); sendSoapString.append(" </soapenv:Body>"); sendSoapString.append("</soapenv:Envelope>"); return sendSoapString; } } 入参可根据实际接口的需要进行修改,各节点可查看接口的soap入参要求,动态处理或者写死都行; 由于我的调用服务只有一个,并且有多个方法,所以入参method需要动态处理;
下面是接口调用:
public class SoapUtil { public static String getWebServiceAndSoap(String url,String isClass,String isMethod,StringBuffer sendSoapString) throws IOException { String result = ""; String soap = sendSoapString.toString(); if (soap == null) { return null; } URL soapUrl = new URL(url); URLConnection conn = soapUrl.openConnection(); conn.setUseCaches(false); conn.setDoInput(true); conn.setDoOutput(true); conn.setRequestProperty("Content-Length", Integer.toString(soap.length())); conn.setRequestProperty("Content-Type", "text/xml; charset=utf-8"); // 调用的接口方法是 conn.setRequestProperty(isClass,isMethod); OutputStream os = conn.getOutputStream(); OutputStreamWriter osw = new OutputStreamWriter(os, "utf-8"); osw.write(soap); osw.flush(); osw.close(); // 获取webserivce返回的流 InputStream is = conn.getInputStream(); if (is!=null) { byte[] bytes = new byte[0]; bytes = new byte[is.available()]; is.read(bytes); String str = new String(bytes); return str; }else { return null; } } }
解读一下上面的工具类:
url:是对接服务地址,以"?wsdl"结尾的地址;
isClass:接口类名,在对方提供的wsdl文件中可以查到,我这里的是"LvYunkangWebservice";
isMethod:调用方法名
sendSoapString:拼接好的soap报文 该工具类在实际测试中,发现最终返回的报文,会出现乱码现象,查阅得知,应该是跟InputStream按字节解析有关。所以,对上述工具类进行简单的修改,也就是对返回结果部分做一下修改(标红的部分)
public class SoapUtil { public static String getWebServiceAndSoap(String url,String isClass,String isMethod,StringBuffer sendSoapString) throws IOException { String result = ""; String soap = sendSoapString.toString(); if (soap == null) { return null; } URL soapUrl = new URL(url); URLConnection conn = soapUrl.openConnection(); conn.setUseCaches(false); conn.setDoInput(true); conn.setDoOutput(true); conn.setRequestProperty("Content-Length", Integer.toString(soap.length())); conn.setRequestProperty("Content-Type", "text/xml; charset=utf-8"); // 调用的接口方法是 conn.setRequestProperty(isClass,isMethod); OutputStream os = conn.getOutputStream(); OutputStreamWriter osw = new OutputStreamWriter(os, "utf-8"); osw.write(soap); osw.flush(); osw.close(); // 获取webserivce返回的流 InputStream is = conn.getInputStream(); if (is != null) { InputStreamReader isr = new InputStreamReader(is, "UTF-8"); BufferedReader br = new BufferedReader(isr); StringBuilder sb = new StringBuilder(); String temp = null; while(null != (temp = br.readLine())) { sb.append(temp); } result = sb.toString(); is.close(); isr.close(); br.close(); } return result; } }
解析返回的报文:
这里先给大家看一下,我的拿到的报文返回示例:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <ns2:getResultResponse xmlns:ns2="http://webservice.taikang.com/"> <return> <message>访问成功</message> <result>true</result> </return> </ns2:getResultResponse > </soap:Body> </soap:Envelope>
按节点分级解析的方式,返回Map即可
public static Map<String,String> XMLtoData(String xml) throws DocumentException { Map map = new HashMap(); List<Data> dataList = new ArrayList<>(); Document doc = DocumentHelper.parseText(xml); //获取根元素,准备递归解析这个XML树 Element root = doc.getRootElement(); //获取到data的集合 List<Element> mzList = root.element("Body").element("getResultResponse").elements("return"); //遍历data集合 for (Element e : mzList) { List<Element> elements = e.elements(); //遍历将元素中的key和value存到map中 for (Element item : elements) { if (!StringUtils.isEmpty(item.getText())) { map.put(item.getName(), item.getText()); } } } return map; } 注意:
List<Element> mzList = root.element("Body").element("getResultResponse").elements("return"); 节点可以按需求获取,即:root.element("**").element("**")................elements("**")
上述是两种工具类调用Webservice接口的方式,请多指教!
来源:https://www.cnblogs.com/zeropc/p/14257859.html
最新更新
带有参数的装饰器
类装饰器
django中的auth模块与admin后台管理
python的日期处理
字符串常用方法
基本数据类型概述
python-map()函数基本用法
python带你实现任意下载AcFun视频数据~
bbs项目之注册功能
变量的定义和使用
三大常用数据库事务详解之三:事务运行
三大常用关系型数据库事务详解之二:基
三大关系型数据库事务详解之一:基本概
MongoDB常用命令(2)
MongoDB基本介绍与安装(1)
SQLServer触发器调用JavaWeb接口
SQL Server索引的原理深入解析
SqlServer2016模糊匹配的三种方式及效率问题
SQL中Truncate的用法
sqlserver 多表关联时在where语句中慎用tri
VB.NET中如何快速访问注册表
ASP.NET中图象处理过程详解
Vue(1)Vue安装与使用
JavaScript 语言入门
js将一段字符串的首字母转成大写
纯原生html编写的h5视频播放器
H5仿原生app短信验证码vue2.0组件附源码地
TypeScript(4)接口
TypeScript(3)基础类型
TypeScript(2)WebStorm自动编译TypeScript配置