前语
首先自我介绍,本人从事java开发,刚跳槽到了一家传统生产公司,主要负责公司的BI以及和sap对接的开发工作。为什么要写这篇微博呢?因为在网上找了好多关于解析wsdl(sap发布的webService的内容为wsdl),都于是无补,最后终于再茫茫的教程中完成了,与sap 对接的java开发。
技术:axis2
Axis框架来自 Apache 开放源代码组织,它是基于JAVA语言的最新的 SOAP 规范(SOAP 1.2)和 SOAP withAttachments 规范(来自 Apache Group )的开放源代码实现。有很多流行的开发工具都使用AXIS作为其实现支持Web服务的功能,能用到的地方有很多,本篇着重讲通过axis2解析webservice。
讲解:方法一
不多说,干货来了。
对于一般的webservice借口,使用axis2有两种方法。
1、 直接再maven里面添加依赖
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-adb</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-transport-http</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-transport-local</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-kernel</artifactId>
<version>1.6.2</version>
</dependency>
这个是简单的通过门店编号(IKUNNR)查询门店是否存在。但这个会有一个弊端就是就是sap的webservice会出错。大概是wsdl格式不正确,所以无法解析,具体原因大家可以再网上找一下。
讲解:方法二
本方法是本人亲测有效,而且很方便。
通过使用axis2本地操作,将webservice接口自动生成java实例,将接口中的函数封装,拿过来直接可以使用。但是其中有几个坑,咱们一步一步来说。
一、下载 axis2,https://download.youkuaiyun.com/download/weixin_42482346/11110168.
可直接下载版本是1.7.9
打开是
二、设置环境变量 %AXIS2_HOME% value E:\axis2-1.7.9\axis2-1.7.9 然后再path中在后面添加%AXIS2_HOME%/bin;
三、开始解析
进入axis2的bin目录,在地址栏输入cmd,直接打开dos窗口,输入命令 wsdl2 -uri “webService接口” -p (webservice实例所在项目的路径) -o (在bin目录中的文件)
正常解析过程汇报log4j的错误,不用理睬。结束之后会在设置的路径里面发现两个java文件。
其中xxxStub.java是主要的接口类(重要),xxxHandler.java 是是解析类,不用理睬。
重点坑: 在解析命令中 -p 一定要是解析的实例所在你项目的路径。例如: com.test.SapDomain
那么这里就应该一字不差的,因为它在解析的过程中,自动将路径映射至实例中。如果要更改,你需要进入实例代码中,一个一个的改动。吃过亏,希望大家不要踩坑。
四、有了实例 ,按照java的套路肯定是需要相应的jar包,这个大家不用担心。axis2已经准备好了,在主目录中的lib目录中就有,可以直接copy到项目中。然后将实例复制到项目中相应的路径中。
重点坑:在lib中有个jar包gson-2.1.jar,如果不注意也拷贝进去,运行汇报 not found method。是因为java中已经有此类了,再加入项目可能导致版本冲突,而报错。若出现这个问题,可以将此jar报删掉。
五、代码编写。
需求:根据门店编号查询,门店在sap中是否存在。(入门)
@Test
public void checkKunnrBySap() throws RemoteException {
// TODO Auto-generated method stub
//创建接口实例,此就是xxxStub包对象
ZWEIXICHECKKUNNRStub stub = new ZWEIXICHECKKUNNRStub();
//创建接口中函数的对象
ZWEIXICHECKKUNNRStub.ZweixiCheckKunnr zweixiCheckKunnr = new ZWEIXICHECKKUNNRStub.ZweixiCheckKunnr();
//创建参数对象,并扶植
ZWEIXICHECKKUNNRStub.Char10 char10 = new ZWEIXICHECKKUNNRStub.Char10();
char10.setChar10("1100");
//给函数参数复制
zweixiCheckKunnr.setIKunnr(char10);
//接口实例嗲用函数,方法参数一般是已赋值的函数对象
ZWEIXICHECKKUNNRStub.ZweixiCheckKunnrResponse response = stub.zweixiCheckKunnr(zweixiCheckKunnr);
String char1 = response.getECode().getChar1();//输出
System.out.println(char1);
}
讲解一下参数的设定,因为sap对字段管控严格,且与java的数据类型的差异,只能通过接口中封装的方法来换类型。
需求:根据门店编号和日期,查询门店单据(进阶)
这个的难点在于sap的传回的数据的复杂性(为表结构)。
分为两部分,单据head和item。可以简单的看作为两个表(head表与item表),且head和item为一对多的关系。一个单据抬头对应多个行项目
head表
key | value |
---|---|
单据编号 | 010 |
日期 | 2019-04-12 |
门店编号 | 1000 |
送货路线 | 上海-南京 |
item表
单据编号 | 产品编号 | 产品名 | 单价 |
---|---|---|---|
010 | 2000 | bbb | 1111 |
010 | 10000 | ccc | 2222 |
010 | 3000 | ddd | 3333 |
010 | 4000 | eee | 444 |
重点:两张表中一点要有相同的字段,类似与sql的外键,可以让head与item表能对应。
知道了返回的参数模型,就知道该怎么对传回的数据进行解析了。以后遇到相同的sap结构也可以照搬。
不多说源码奉上
首先是单据对象delivery
import java.util.Date;
import java.util.List;
public class SapDelivery {
private String head_Vbeln;
private String head_Lfdat;
private String head_Kunnr;
private String head_Zname;
private String head_Zmdlx;
private String head_Zmddz;
private String head_Zmdxl;
private String head_Zxsdq;
private List<SapDeliveryItem> sapDeliveryItems;