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. XSS挑战赛(1)

    以前囫囵吞枣做过一遍,现在从头再来 第一关网址为:http://127.0.0.1/xss-labs-master/level1.php?name=test 而页面上显示了用户test,name可控, ...

  2. 《Eroico》关卡与操作设计

    操作设计: 没有给明操作教程,操作全靠蒙,只有改建的位置可以看到. 但游戏的难度并没有给玩家适应操作感,随着难度提升怪物血量增厚,但怪物并没有僵直英雄却有僵直.第一个小猫妖便给了玩家一个痛击. 方向键 ...

  3. 深入解析volatile关键字

    前言 很高兴遇见你~ 欢迎阅读我的文章. volatile关键字在Java多线程编程编程中起的作用是很大的,合理使用可以减少很多的线程安全问题.但其实可以发现使用这个关键字的开发者其实很少,包括我自己 ...

  4. beautifulsoup使用记录

    1.关于编码问题, 被编码为了?号,解决办法是:content.prettify(formatter="html"),这样 存到数据库里面的就是html代码.

  5. STL——容器(deque) deque 的大小

    1. deque 的大小 deque.size();              //返回容器中元素的个数 1 #include <iostream> 2 #include <dequ ...

  6. Java8新增的这些集合骚操作,你掌握了嘛?

    目录 Iterable的forEach Iterator的forEachRemaining Collection的removeIf Stream操作 List的replaceAll List的sort ...

  7. JavaSE09-(练手)简易学生管理系统

    1.学生管理系统实现步骤 案例需求 系统主要功能如下: 添加学生:通过键盘录入学生信息,添加到集合中 删除学生:通过键盘录入要删除学生的学号,将该学生对象从集合中删除 修改学生:通过键盘录入要修改学生 ...

  8. 未雨绸缪,数据保护之NBU介质备份

    摘要:华为GaussDB目前已支持NBU介质的备份与恢复,本文主要描述了华为GaussDB数据库和NetBackup对接进行备份.恢复的配置方法与性能调优方法. 一.简介 企业要想避开自然灾难和站点中 ...

  9. python去除文件中重复的行

    去除文件中重复的行 import os with open('db.txt','r',encoding='utf-8') as read_f,\ open('.db.txt.swap','w',enc ...

  10. 抢先看:笔者亲历的2020年中国.NET开发者大会活动纪实

    2020年中国.NET开发者大会活动纪实 1 2020年12月19日的苏州工业园区,天公作美,阳光明媚,气象迷人,正是一个搞事的好日子.在这里,数百名中国.NET开发者们汇聚一堂,怀揣着激情和梦想,一 ...