背景:接公司一业务,对方只提供了一个wsdl文件/接口,无文档对接
了解webservice
Web Service是一个平台独立的,低耦合的,自包含的、基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集)标准来描述、发布、发现、协调和配置这些应用程序,用于开发分布式的交互操作的应用程序。 Web Service技术, 能使得运行在不同机器上的不同应用无须借助附加的、专门的第三方软件或硬件, 就可相互交换数据或集成。依据Web Service规范实施的应用之间, 无论它们所使用的语言、 平台或内部协议是什么, 都可以相互交换数据。Web Service是自描述、 自包含的可用网络模块, 可以执行具体的业务功能。
特点:
- 解耦
- 不限开发语言,协议
- 单体架构协同
Java开发步骤
服务端开发
搭建服务端server流程,一般是开发接口,发布wsdl文件或者接口。 http://localhost:8081/test/api?wsdl 这个wsdl文件就是服务端提供的相关接口描述
客户端解析
但是作为使用者,我们要做的就是使用客户端去解析wsdl接口文件,进行调用。 网上找了一大堆,基本有两种方式去构建客户端:
- 代理调用
package com.it.client;
import com.it.interceptor.ClientLoginInterceptor;
import com.it.service.MessageService;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
public class CXFProxyClient {
private static final String ADDRESS = "http://localhost:8080/services/MessageService?wsdl"; // WebService服务地址
public static void main(String[] args) {
JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
jaxWsProxyFactoryBean.setAddress(ADDRESS);
jaxWsProxyFactoryBean.setServiceClass(MessageService.class);
jaxWsProxyFactoryBean.getOutInterceptors().add(
new ClientLoginInterceptor("admin","123456") // 设置用户名,密码
);
MessageService messageService = (MessageService)jaxWsProxyFactoryBean.create();
String echo = messageService.echo("[webservice proxy invoke]");
System.out.println("echo = " + echo);
}
}
- 动态调用
package com.it.client;
import com.it.interceptor.ClientLoginInterceptor;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
public class CXFDynamicClient {
private static final String ADDRESS = "http://localhost:8080/services/MessageService?wsdl"; // WebService服务地址
public static void main(String[] args) throws Exception {
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient(ADDRESS);
client.getOutInterceptors().add(new ClientLoginInterceptor("admin","123456"));
String message = "dynamic";
Object[] result = client.invoke("echo", message);
System.out.println(result);
}
}
盘点踩坑
使用jdk自带工具解析失败
这是用到的命令
PS D:\Program Files\Java\jdk1.8.0_202\bin> .\wsimport -d D:\code\webserve -keep -verbose -Xauthfile D:\code\webserve\aaa\11.txt http://xxxx.xxxx.xxxx:8000/sap/bc/srt/wsdl/flv_xxxxxxxx1/xxxxxx/xxx/xxxxx/sap/zfi_fun_012/800/zfi_fun_012/zfi_fun_012?sap-client=800?WSDL
正在解析 WSDL...
[ERROR] Server returned HTTP response code: 401 for URL: http://xxxxx.xxxxx.xxxx:8000/sap/bc/zfi_fun_012/800/zfi_fun_012/xxxxxxx?sap-client=800?WSDL, "http://xxxxx.xxxxx.xxxx/zfi_fun_012/800/zfi_fun_012/zfi_fun_012?sap-client=800?WSDL" 需要授权, 请在C:\Users\Administrator.metro\auth中提供具有读取访问权限的授权文件, 或者使用 -Xauthfile 指定授权文件并在每一行上使用以下格式提供授权信息: http[s]://user:password@host:port//<url-path>
Exception in thread "main" com.sun.tools.internal.ws.wscompile.AbortException
at com.sun.tools.internal.ws.wsdl.parser.MetadataFinder$WSEntityResolver.resolveEntity(MetadataFinder.java:187)
at com.sun.tools.internal.ws.wsdl.parser.DOMForest.parse(DOMForest.java:198)
at com.sun.tools.internal.ws.wsdl.parser.DOMForest.parse(DOMForest.java:134)
at com.sun.tools.internal.ws.wsdl.parser.MetadataFinder.parseWSDL(MetadataFinder.java:96)
at com.sun.tools.internal.ws.wscompile.WsimportTool.buildWsdlModel(WsimportTool.java:424)
at com.sun.tools.internal.ws.wscompile.WsimportTool.run(WsimportTool.java:190)
at com.sun.tools.internal.ws.wscompile.WsimportTool.run(WsimportTool.java:168)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.tools.internal.ws.Invoker.invoke(Invoker.java:159)
at com.sun.tools.internal.ws.WsImport.main(WsImport.java:42)
由于对方地址server加了密,使用JDK自带工具wsimport,老是提示使用-Xauthfile,这个我也加了,还是报错,此路不通,如果对方server没有加密,此方法可以试试。
使用Idea解析
由于这个webservice是上古技术,所以越新的idea 对其支持的力度越小,这个对应的入库隐藏的越深,比较恶心。这里以IntelliJ IDEA 2021.3.3 (Ultimate Edition) 为例子。 按照网上说的,在这个里面找到webservice的入口,找不到网上说的webservice入口,一顿操作,按时下班。 正确姿势:
- 新建java项目,一路ok即可
- 添加框架
- 看到熟悉的东西了,一顿卡卡点
点击ok
由于 accessExternalSchema 属性设置的限制而不允许 'file' 访问, 因此无法读取方案文档 '***.xsd'
芭比q了,又报错???
快请如来佛祖!!!
jdk1.8版本兼容问题
速切1.6版本
快乐这不就来了
小结
这玩意,狗都不用。
鸣谢@涛儿