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;
}
}
解读一下入参和几个重要的参数:
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接口的方式,请多指教!
 

关于Webservice接口对接相关总结的更多相关文章

  1. webservice 接口报404错误问题小结

    1 背景介绍 生产环境有两台应用服务器(RAC),EBS版本是12.1.3,服务器操作系统版本linux 节点一:10.192.80.87 节点二:10.192.80.88 20180512(周六) ...

  2. 从xfire谈WebService接口化编程

    前段时间有博友在看我的博文<WebService入门案例>后,发邮件问我关于WebService 接口在java中的开发,以及在实际生产环境中的应用.想想自己入职也有一段时间了,似乎也该总 ...

  3. Web Api 与 Andriod 接口对接开发经验

    最近一直急着在负责弄Asp.Net Web Api 与 Andriod 接口开发的对接工作! 刚听说要用Asp.Net Web Api去跟 Andriod 那端做接口对接工作,自己也是第一次接触Web ...

  4. Asp.Net Web Api 与 Andriod 接口对接开发经验,给小伙伴分享一下!

    最近一直急着在负责弄Asp.Net Web Api 与 Andriod 接口开发的对接工作! 刚听说要用Asp.Net Web Api去跟 Andriod 那端做接口对接工作,自己也是第一次接触Web ...

  5. 互联网 免费的WebService接口

    winform开发暂告于段落,最近再用webservice写接口,接下来的一段时间应该偏向于此方向. (转)一批的免费webservice接口,没有技术含量,只是写在这里做个记忆 股票行情数据 WEB ...

  6. Asp.Net Web Api 与 Andriod 接口对接开发

    Asp.Net Web Api 与 Andriod 接口对接开发经验,给小伙伴分享一下!   最近一直急着在负责弄Asp.Net Web Api 与 Andriod 接口开发的对接工作! 刚听说要用A ...

  7. 如何高效的进行WebService接口性能测试

    版权声明:本文为原创文章,转载请先联系并标明出处 关于接口测试的理解,主要有两类,一类是模块与模块间的调用,此类接口测试应该归属于单元测试的范畴,主要测试模块与模块之间联动调用与返回.此类测试大多关注 ...

  8. php调用webservice接口

    项目中使用到了调用三方厂商webService接口.他的接口类似为http://haha.cn:86/BaseInfoService.svc?wsdl,在这里我注意到了"wsdl" ...

  9. ws-trust、域、webservice接口的总结

    最近燃料公司门户做了一个待办的汇总,从三个数据源拿数据汇总到首页,这三个数据源分别是域认证的接口,域认证的webservices,证书加密的接口,下面就这些接口,做一下简单总结 1 pfx证书的探索过 ...

随机推荐

  1. 西湖论剑2020MISC-Yusa_yyds

    非常规USB流量分析 附件下载: 链接:https://pan.baidu.com/s/1Gjgj1EH9qmX0PYi21uYlDg 提取码:x9xn 先提取USB流量数据,使用工具: https: ...

  2. POJ_1961

    Period Time Limit: 3000MS   Memory Limit: 30000K Total Submissions: 19817   Accepted: 9640 Descripti ...

  3. IntelliJ IDEA2019.3.2破解/永久激活/安装教程

    我想大家用过史上最好的开发工具就是idea了,没有之一!看到大家都在找idea的激活教程,今天我也在这里跟大家分享一下. 本教程针对现在官网针对的版本是idea2019.3.2,为防止以后会更新破解失 ...

  4. 关于select下拉框选择触发事件

    最开始使用onclick设置下拉框触发事件发现会有一些问题: <select> <option value="0" onclick="func0()&q ...

  5. LeetCode初级算法之字符串:7 整数反转

    整数反转 题目地址:https://leetcode-cn.com/problems/reverse-integer/ 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转. 示例 ...

  6. SQL直接生成实体属性,简单粗暴型

    在java开发中,不可避免的要碰到根据表生成对应的实体,这个过程是比较机器且繁琐的,我也用过一些逆向工程的工具,比如IDEA自带的生成实体,还有网上开源的工具,用起来也是可以的. 我现在开发用的持久层 ...

  7. Codeforces Edu Round 51 A-D

    A. Vasya And Password 模拟题,将所缺的种类依次填入"出现次数$ >1 $"的位置,替换掉Ta即可. #include <iostream> ...

  8. 图论-zkw费用流

    图论-zkw费用流 模板 这是一个求最小费用最大流的算法,因为发明者是神仙zkw,所以叫zkw费用流(就是zkw线段树那个zkw).有些时候比EK快,有些时候慢一些,没有比普通费用流算法更难,所以学z ...

  9. 120多套各种类别微信小程序模板源码打包下载

    120多套各种类别微信小程序模板源码打包下载,以下是部分截图欢迎下载!120多套各种类别微信小程序模板源码打包下载 下载地址:https://pan.baidu.com/s/1Cfqyc9p2ZDOc ...

  10. Vue高仿网易云网页端源码

      音乐播放器虽然烂大街了,但是作为前端没自己撸一个一直是个遗憾, 而且偶然间发现 pc 端 web 版的网易云音乐做的实在是太简陋了, 社区仿 pc 客户端的网易云也不多见,为了弥补这个遗憾, 就用 ...