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. 由Java 15废弃偏向锁,谈谈Java Synchronized 的锁机制

    Java 15 废弃偏向锁 JDK 15已经在2020年9月15日发布,详情见 JDK 15 官方计划.其中有一项更新是废弃偏向锁,官方的详细说明在:JEP 374: Disable and Depr ...

  2. 从零开始的sql注入学习(挖坑不填)

    首先,本人是小白,这篇文章也只是总结了一下大佬们的sql注入方法,要是有错,请各位大佬指出,以便学习. 虽然我是菜鸡,但是太过基础的sql注入问题也就不再重复的解释了.直接从常用的说起. 实战中常用的 ...

  3. 《深入理解计算机系统》实验一 —Data Lab

    本文是CSAPP第二章的配套实验,通过使用有限的运算符来实现正数,负数,浮点数的位级表示.通过完成这13个函数,可以使我们更好的理解计算机中数据的编码方式. 准备工作   首先去官网Lab Assig ...

  4. 小程序editor篇-基本使用图片上传

    今天小程序项目内,要弄一个editor,富文本编辑功能,支持图文并茂,前几天刚好看了小程序的demo应用,刚好看到editor这个东东,那就安排! 官网示例git地址 大概看了下文档,拉下官方示例,看 ...

  5. ARC109D - L

    平面上一开始有三个点\((0,0),(0,1),(1,0)\)形成成L形(点连续),每次操作可以将一个点改变位置,使得得到的仍然是L形.给出终止L形的位置,问移动的最小步数. \(|x|,|y|\le ...

  6. 题解 CF504E 【Misha and LCP on Tree】

    PullShit 倍增和树剖的差距!!! 一个 TLE, 一个 luogu 最优解第三!!! 放个对比图(上面倍增,下面轻重链剖分): 不过这是两只 log 非正解... Solution \(LCP ...

  7. redis学习之——持久化RDB 和AOF

    RDB: 在指定的时间间隔内将内存中的数据集快照写入磁盘, 也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里.rdb 保存的是dump.rdb文件 RDB工作原理: Redis会 ...

  8. ajax与浏览器请求的差异对比.png

  9. Canal监听mysql

    安装mysql5.7,并开启binlog 安装mysql 开启binlog find / -name my.cnf 找到这个文件 添加几行 [mysqld] log-bin=mysql-bin # 开 ...

  10. Consul集成Envoy实践

    单节点Consul集成Envoy进行安全服务通信 前言 ​ Consul Service Mesh通过授权和加密来保护服务之间的通信,还可以拦截有关服务到服务通信的数据并将其呈现给监视工具.我们可以使 ...