0%

客户端调用webservice服务方法

客户端调用webservice服务方法

web service 介绍

Web Service 也叫XML Web Service, Web Service 是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量级的独立的通讯技术。是通过SOAP在Web上提供的软件服务,使用WSDL文件进行说明,并通过UDDI进行注册。

XML :(Extensible Markup Language)扩展型可标记语言。面向短期的临时数据处理、面向万维网络,是Soap的基础。

Soap :(Simple Object Access Protocol)简单对象存取协议。是XML Web Service 的通信协议。当用户通过UDDI找到你的WSDL描述文档后,他通过可以SOAP调用你建立的Web服务中的一个或多个操作。SOAP是XML文档形式的调用方法的规范,它可以支持不同的底层接口,像HTTP(S)或者SMTP。

WSDL :(Web Services Description Language) WSDL 文件是一个 XML 文档,用于说明一组 SOAP 消息以及如何交换这些消息。大多数情况下由软件自动生成和使用。

UDDI :(Universal Description, Discovery, and Integration) 是一种根据描述文档来引导系统查找相应服务的机制。UDDI利用SOAP消息机制(标准的XML/HTTP)来发布,编辑,浏览以及查找注册信息。它采用XML格式来封装各种不同类型的数据,并且发送到注册中心或者由注册中心来返回需要的数据。

所以,webservice 是基于http的soap协议传输数据 webservice = soap = http + xml

其中,发布Web Service服务的叫服务端,可以用于构建Web Service服务的java框架有 Axis2CXF;调用Web Service服务的叫做客户端,同样客户端调用webservice服务也有多种方式:

  • jdk 原生调用
  • 用import命令生成客户端代码
  • 基于cxf类库的两种调用方式或客户端代码生成
  • 基于axis2类库调用方式或客户端代码生成
  • httpClient调用方式
  • SoapUI 客户端工具调用

目前尝试过的是用axis2生成客户端代码的方式。优点不用拼装xml,代码更简洁;缺点wsdld变化(如新增接口或参数)后需要重新生成客户端代码

axis2生成客户端代码&使用

1. 下载axis2

http://axis.apache.org/axis2/java/core/download.html
建议下载 axis2-x.x.x-bin.zip 包,如:axis2-1.7.9-bin.zip

axis2提供了一个wsdl2java.bat命令可以根据WSDL文件自动产生调用WebService的代码。
wsdl2java.bat命令可以在<Axis2安装目录>/bin目录中找到。
注意:生成前,1.java环境必须正常 2.设置AXIS2_HOME环境变量,该变量值是<Axis2安装目录>

解压 axis2-x.x.x-bin.zip ,并进入使用cmd进入<Axis2安装目录>/bin目录,执行如下命令

1
C:\Users\admin\Downloads\axis2-1.7.9\bin>wsdl2java -uri http://localhost:8080/services/TestService?wsdl -p com.example.demo.test -s -o generate_java

-url : 参数指定了wsdl文件的路径,可以是本地路径,也可以是网络路径
-p : 参数指定了生成的Java类的包名
-o : 参数指定了生成的一系列文件保存在位置,此处是 bin\generate_java目录下

在执行完上面的命令后,当前目录下多了个generate_java目录

1
2
3
4
5
6
7
8
-build.xml
-src/
-com/
-example/
-demo/
-test/
-TestServiceStub.java
-ExceptionException.java

2. 项目中使用生成的代码

引入axis2依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!-- webservice axis2 -->
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-kernel</artifactId>
<version>1.7.9</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-adb</artifactId>
<version>1.7.9</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-transport-local</artifactId>
<version>1.7.9</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-transport-http</artifactId>
<version>1.7.9</version>
</dependency>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-jaxws</artifactId>
<version>1.7.9</version>
</dependency>

生成代码放入工程

直接将生成的代码放入工程对应目录,不要对生成代码做任何修改。

新建TestService

建议新建一个Service 对Stub的接口和参数进行包装,统一通过它对外提供服务

注入TestServiceStub

1
2
@Resource(name = "testServiceStub")
private TestServiceStub testServiceStub;

接口包装示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
* 用户卡号或用户编号查询用户
* @param certificateNo 用户卡号或用户编号
* @return
*/
public ChargeServiceStub.UserInfoData[] getUserByID(String certificateNo, String orderId) throws RemoteException, ExceptionException {

// 请求参数
ChargeServiceStub.UserInfoParam userInfoParam = new ChargeServiceStub.UserInfoParam();
setBaseParamInfo(userInfoParam, orderId);
userInfoParam.setCertificateNo(certificateNo);

// 签名
String[] keys = {"bankCode","chgBranch","chgTeller","orderId","certificateNo"};
String[] values = {bankCode,chgBranch,chgTeller,orderId,certificateNo};
userInfoParam.setSignature(SignatureUtil.createSignature(signKey,keys,values));

// 请求
ChargeServiceStub.GetUserByID getUserByID = new ChargeServiceStub.GetUserByID();
getUserByID.setParamObj(userInfoParam);
ChargeServiceStub.GetUserByIDResponse response = chargeServiceStub.getUserByID(getUserByID);

// 结果
ChargeServiceStub.UserInfoData[] dataArray = response.get_return();
LOGGER.info("====|getUserByID|==response==>{}", JSONArray.toJSONString(dataArray));
return dataArray;
}

文档参考说明

  • 本文档参考了 urumqi-item-servie 的热力缴费事项接入方式

  • 还有一些事项服务(如:city-socialBureau)使用的是cxf的动态模式调用,到处是写死的xml元素名称,可复用性很差,所以没有使用。应该有更优雅的方式,还需要在研究

  • 因为可以用http方式请求,所以可以考虑将 webservice的调用 也封装到 hfi-okhttp 中,后面可以在研究下。