背景
最近在对接泛微OA,其中使用到了 webservice 进行交互。于是趁着周末的时候学习一下。
WebService 是什么
W3C组织对其的定义如下,它是一个软件系统,为了支持跨网络的机器间相互操作交互而设计。Web Service服务通常被定义为一组模块化的API,它们可以通过网络进行调用,来执行远程系统的请求服务。
三要素
WebService的三要素是:
- SOAP (Simple Object Access Protocol):简易对象访问协议,soap用来描述传递信息的格式。
- WSDL (WebServices Description Language):Web服务描述语言,用来描述如何访问具体的接口。
- UDDI (Universal Description Discovery and Integration):通用描述、发现及整合,用来管理、分发、查询webService。
开发示例
下面是练手的一个例子。
服务端
- 定义接口
public interface MobileAddress {
/**
* 根据手机号查询归属地
* @param mobile
* @return
*/
String getAddressByMobile(String mobile);
}
- 实现类,使用 @WebService 标注类
@WebService
public class MobileAddressImpl implements MobileAddress {
public String getAddressByMobile(String mobile) {
// 这里写业务逻辑
return mobile + "归属地是:上海";
}
}
- 发布 webservice
// 服务启动成功之后,通过下面这种格式访问:Webservice地址+?wsdl
// 例如: http://127.0.0.1:9999/mobile?wsdl
public class JaxwServer {
public static void main(String[] args) {
Endpoint.publish("http://127.0.0.1:9999/mobile", new MobileAddressImpl());
System.out.println("WebService 服务启动成功!");
}
}
服务发布成功后,访问 http://127.0.0.1:9999/mobile?wsdl 会展示类似下面的页面:
客户端
- 通过 wsimport 命令 + wsdl文档,获取客户端java程序(stub桩,本地代理接口类实例)
wsimport 是 jdk 自带的命令。
用法: wsimport [options] <WSDL_URI>
\其中 [options] 包括:
-b <path> 指定 jaxws/jaxb 绑定文件或附加模式
(每个 <path> 都必须具有自己的 -b)
-B<jaxbOption> 将此选项传递给 JAXB 模式编译器
-catalog <file> 指定用于解析外部实体引用的目录文件
支持 TR9401, XCatalog 和 OASIS XML 目录格式。
-d <directory> 指定放置生成的输出文件的位置
-encoding <encoding> 指定源文件所使用的字符编码
-extension 允许供应商扩展 - 不按规范
指定功能。使用扩展可能会
导致应用程序不可移植或
无法与其他实现进行互操作
-help 显示帮助
-httpproxy:<host>:<port> 指定 HTTP 代理服务器 (端口默认为 8080)
-keep 保留生成的文件
-p <pkg> 指定目标程序包
-quiet 隐藏 wsimport 输出
-s <directory> 指定放置生成的源文件的位置
-target <version> 按给定的 JAXWS 规范版本生成代码
默认为 2.2, 接受的值为 2.0, 2.1 和 2.2
例如, 2.0 将为 JAXWS 2.0 规范生成兼容的代码
-verbose 有关编译器在执行什么操作的输出消息
-version 输出版本信息
-wsdllocation <location> @WebServiceClient.wsdlLocation 值
-clientjar <jarfile> 创建生成的 Artifact 的 jar 文件以及
调用 Web 服务所需的 WSDL 元数据。
-generateJWS 生成存根 JWS 实现文件
-implDestDir <directory> 指定生成 JWS 实现文件的位置
-implServiceName <name> 生成的 JWS 实现的服务名的本地部分
-implPortName <name> 生成的 JWS 实现的端口名的本地部分
\扩展:
-XadditionalHeaders 映射标头不绑定到请求或响应消息不绑定到
Java 方法参数
-Xauthfile 用于传送以下格式的授权信息的文件:
http://username:password@example.org/stock?wsdl
-Xdebug 输出调试信息
-Xno-addressing-databinding 允许 W3C EndpointReferenceType 到 Java 的绑定
-Xnocompile 不编译生成的 Java 文件
-XdisableAuthenticator 禁用由 JAX-WS RI 使用的验证程序,
将忽略 -Xauthfile 选项 (如果设置)
-XdisableSSLHostnameVerification 在提取 wsdl 时禁用 SSL 主机名
验证
\示例:
wsimport stock.wsdl -b stock.xml -b stock.xjb
wsimport -d generated http://example.org/stock?wsdl
输入以下命令: wsimport -s E://ws -d E://ws/classes -p com.rh.example.ws.client.stub http://127.0.0.1:9999/mobile?wsdl
出现上面的情况是因为 服务端的程序关闭了,服务端开启之后:
可以看到代码已经生成:
2. 将生成的代码直接拷贝到工程中,写一个简单的main 方法去调用测试一下
public class JaxwsClient {
public static void main(String[] args) {
// 1. 实例化服务类
MobileAddressImplService mas = new MobileAddressImplService();
// 2. 通过服务类得到本地代理类
MobileAddressImpl ma = mas.getMobileAddressImplPort();
// 3. 调用本地代理对象的方法,得到数据
System.out.println(ma.getAddressByMobile("13822225555"));
}
}
public class JaxwsClient2 {
public static void main(String[] args) throws MalformedURLException {
// 下面的参数都可以在 生成的 标注 @WebServiceClient 的类中看到
Service service = Service.create(
new URL("http://127.0.0.1:9999/mobile?wsdl"),
new QName("http://impl.server.ws.example.rh.com/", "MobileAddressImplService")
);
MobileAddressImpl ma = service.getPort(MobileAddressImpl.class);
System.out.println(ma.getAddressByMobile("13822225555"));
}
}
参考地址
https://www.cnblogs.com/beyondcj/p/6271106.html