目录

概述

特别提醒

Java JDK wsimport.exe

 解析组件 's:schema' 时出错

Apache CXF wsdl2java 工具包

cxf-codegen-plugin maven 插件


概述

1、对于公司内部,或者条件允许的情况下,找对方开发人员直接获取 webservice 服务端的接口源码也是可以的,粘贴到客户端就能用。

2、客户端调用webservice服务的方式有许多种,并不是所有的方式都需要根据 wsdl 文件生成客户端类,如果需要生成,则通常有以下几种方式。

3、温馨提醒:如果使用浏览器在线访问 wsdl 地址,复制内容粘贴到本地创建 xxx.wsdl 文件时,建议使用 google Chrome 浏览器,某次使用的 firefox 复制的内容少了一些东西,导致文件内容不完整而报错。

特别提醒

1)代理类中有些类相互引用时,使用的是绝对地址,所以要么是生成的时候,提前指定好路径,要么是修改报错的路径为实际路径。

2)无论是下面哪种方式,都可以使用在线url地址,或者本地文件进行生成,所以生成的服务类代码中也是在线地址或者本地地址,必须要能够正常访问。如果是本地文件,则建议将 wsdl 文件放在项目中(资源目录下),这样就可以和项目一起移动,否则如果将来项目移动了,而忘了本地的 wsdl 文件,显然运行就报错了。

Java JDK wsimport.exe

1、Java JDK 的 bin文件夹下有一个 wsimport.exe 工具,可依据 wsdl 文件生成相应的类文件,将生成好的类文件拷贝到需要使用的项目中,就可以像调用本地的类一样调用 webService 提供的方法。

2、wsimport.exe 工具可以用于非 Java 的 webService 服务器,如用 C# 、.net 等语言编写的 WebService 服务端,只要得到了其 wsdl 文件,则通过 wsimport 即可生成 Java 客户端实现

3、只要在电脑上配置了 Java JDK 的环境变量,则可以在任意目录下使用 cmd 窗口执行 wsimport 命令,输入 wsimport 回车,即可看到命令的格式、以及参数、使用示例等。

4、常用命令如下,只要服务商提供了 wsdl 地址,自己就可以默默的生成类文件然后调用。:

E:\temp\webservice>wsimport -keep -encoding UTF-8 -d E:/temp/webservice/class -s E:/temp/webservice/java -p org.example.webservice.agency -verbose http://localhost:8080/webservice/agencyService?wsdl
正在解析 WSDL...
正在生成代码...
org\example\webservice\agency\AgencyService.java
org\example\webservice\agency\IAgencyService.java
org\example\webservice\agency\ObjectFactory.java
org\example\webservice\agency\QueryAgencyStatInfo.java
org\example\webservice\agency\QueryAgencyStatInfoResponse.java
org\example\webservice\agency\SyncAgencyStatInfo.java
org\example\webservice\agency\SyncAgencyStatInfoResponse.java
org\example\webservice\agency\package-info.java

正在编译代码...
javac -d E:\temp\webservice\class -classpath C:\wmx\software\Java\jdk1.8.0_131/lib/tools.jar;C:\wmx\software\Java\jdk1.8.0_131/classes -Xbootclasspath/p:C:\wmx\software\Java\jdk1.8.0_131\jre\lib\rt.jar;C:\wmx\software\Java\jdk1.8.0_131\jre\lib\rt.jar E:\temp\webservice\java\org\example\webservice\agency\AgencyService.java E:\temp\webservice\java\org\example\webservice\agency\IAgencyService.java E:\temp\webservice\java\org\example\webservice\agency\ObjectFactory.java E:\temp\webservice\java\org\example\webservice\agency\QueryAgencyStatInfo.java E:\temp\webservice\java\org\example\webservice\agency\QueryAgencyStatInfoResponse.java E:\temp\webservice\java\org\example\webservice\agency\SyncAgencyStatInfo.java E:\temp\webservice\java\org\example\webservice\agency\SyncAgencyStatInfoResponse.java E:\temp\webservice\java\org\example\webservice\agency\package-info.java
E:\temp\webservice>

-keep:保留已生成的文件而不覆盖它们。

-encoding:指定源文件所使用的字符编码。防止中文乱码。
-d:指定.class文件的输出目录,此目录必须提前创建好。部署阶段,直接使用 .class 文件也是可以的。
-s:指定.java文件的输出目录,不指定时,默认与 -d 设置的路径一致。
-p:定义所有生成类的包名,不指定时会保持与原来一致。可以在客户端确定一个目录,然后这里指定它,这样生成的所有文件到时候直接粘贴进去连路径都不用改,否则如果找不到路径就会报错。
-verbose:在控制台显示输出信息
-b:指定jaxws/jaxb绑定文件或额外的schemas
-extension:使用扩展来支持SOAP1.2

结尾指定 wsdl 文件路径,可以是在线地址,也可以是本地地址(就是把在线内容复制到本地),如:

        http://localhost:8080/webservice/agencyService?wsdl

        D:\wsdl\agencyService.wsdl

5、生成的文件中主要关注目标接口即可,接口中的内容基本已经和服务端大差不差了,因为是面向接口编程,其他文件基本可以不用关注。

src/main/resources/wsdl/agencyService.wsdl · 汪少棠/web_app - Gitee.com

 解析组件 's:schema' 时出错

1、生成时报错如下,执行失败,出现的原因是 webService 服务端如果是 .net 写的,则使用 Java wsimport.exe 生成时就会报错。

2、开发中如果没有遇到这个错误,自然是最好,万一遇到,则可以一试,亲测有效。

PS E:\wmx\webservice> wsimport -keep -d E:\wmx\webservice -verbose http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl
正在解析 WSDL...
[WARNING] src-resolve.4.2: 解析组件 's:schema' 时出错。在该组件中检测到 's:schema' 位于名称空间 'http://www.w3.org/2001/XMLSchema' 中, 但无法从方案文档 'http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl#types?schema1' 引用此名称空间的组件。如果这是不正确的名称空间, 则很可能需要更改 's:schema' 的前缀。如果这是正确的名称空间, 则应将适当的 'import' 标记添加到 'http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl#types?schema1'。
  http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl#types?schema1的第 44 行
[WARNING] src-resolve: 无法将名称 's:schema' 解析为 'element declaration' 组件。
  http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl#types?schema1的第 44 行
[ERROR] undefined element declaration 's:schema'
  http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl的第 44 行
[ERROR] undefined element declaration 's:schema'
  http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl的第 85 行
Exception in thread "main" com.sun.tools.internal.ws.wscompile.AbortException
        at com.sun.tools.internal.ws.processor.modeler.wsdl.JAXBModelBuilder.bind(JAXBModelBuilder.java:129)
        at com.sun.tools.internal.ws.processor.modeler.wsdl.WSDLModeler.buildJAXBModel(WSDLModeler.java:2283)
        at com.sun.tools.internal.ws.processor.modeler.wsdl.WSDLModeler.internalBuildModel(WSDLModeler.java:183)
        at com.sun.tools.internal.ws.processor.modeler.wsdl.WSDLModeler.buildModel(WSDLModeler.java:126)
        at com.sun.tools.internal.ws.wscompile.WsimportTool.buildWsdlModel(WsimportTool.java:429)
        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)
PS E:\wmx\webservice>

解决办法

1、针对 .net 开发的 webService 服务端,Java wsimport.exe 生成代理类出错解决办法如下:

1)将服务端的 wsdl 文档保存到本地,如 E:\wmx\webservice\weather.wsdl.xml、E:\wmx\webservice\weather.wsdl、E:\wmx\webservice\weather.xml (经实测文件的后缀名其实关系不大,都可以正常生成)

2、修改 wsdl 文档以下内容:
将文件中所有的 <s:element ref="s:schema" /><s:any /> 替换成 <s:any minOccurs="2" maxOccurs="2"/>

2、直接在 wsdl 文档页面右键,选择查看源代码,然后将 Ctrl + S 保存即可,然后便可打开文件,替换其中的内容:

3、此时使用 wsimport.exe 再次生成,便可以正确执行:

Apache CXF wsdl2java 工具包

1、直接从 Apache CXF 官网下载二进制 jar 包,解压后,在 bin 目录下提供了各种转换工具,其中就包括 wadl2java 工具。

https://dlcdn.apache.org/cxf/3.5.7/apache-cxf-3.5.7.tar.gz。兼容JDK8。

https://dlcdn.apache.org/cxf/3.6.2/apache-cxf-3.6.2.tar.gz。JDK11及以上。

https://dlcdn.apache.org/cxf/4.0.3/apache-cxf-4.0.3.tar.gz。JDK11及以上。

百度网盘地址:https://pan.baidu.com/s/1AH8cjP2oZD1PcCPwdribnA 提取码: 9pay。

2、cmd 进入此目录后即可使用这些工具,在 cmd 中可以使用 wsdl2java -help 即可看到所有的参数以及使用方法。常用命令如下

E:\迅雷下载\apache-cxf-3.5.7\bin>.\wsdl2java -keep -encoding UTF-8 -d E:/temp/webservice/cxf/java -compile -classdir E:/temp/webservice/cxf/class -p org.example.webservice.user -verbose http://localhost:8080/webservice/userService?wsdl
Loading FrontEnd jaxws ...
Loading DataBinding jaxb ...
wsdl2java -keep -encoding UTF-8 -d E:/temp/webservice/cxf/java -compile -classdir E:/temp/webservice/cxf/class -p org.example.webservice.user -verbose http://localhost:8080/webservice/userService?wsdl
wsdl2java - Apache CXF 3.5.7

E:\迅雷下载\apache-cxf-3.5.7\bin>

-keep:保留已生成的文件而不覆盖它们。

-encoding:指定生成的代理类的编码,和服务端的一致即可,防止中文乱码

-compile:对生成的 .java 文件进行编译生成 .class 文件。
-d:指定.java文件的输出目录,目录不存在时会自动创建。
-classdir:指定.class 文件的输出目录,目录不存在时会自动创建。
-p:定义所有生成类的包名,不指定时会保持与原来一致。可以在客户端确定一个目录,然后这里指定它,这样生成的所有文件到时候直接粘贴进去连路径都不用改,否则如果找不到路径就会报错。
-verbose:在控制台显示输出信息

结尾指定 wsdl 文件路径,可以是在线地址,也可以是本地地址(就是把在线内容复制到本地),如:

        http://localhost:8080/webservice/userService?wsdl

        D:\wsdl\userService.wsdl

3、直接将生成好的所有代理类导入到客户端中即可使用。 

 src/main/resources/wsdl/userService.wsdl · 汪少棠/web_app - Gitee.com

cxf-codegen-plugin maven 插件

1、插件底层仍然是 Apache cxf ,只是被集成为 maven 插件,方便操作。

<!-- cxf 客户端代码生成插件,根据 wsdl 文件生成客户端java代码 -->
<!-- 打开"Terminal"终端窗口,输入命令:mvn generate-sources 即可自动生成。 -->
<!-- 重复执行命令时,有时不会重复生成代码,此时需要 mvn clean 清理一下。-->
<plugin>
	<groupId>org.apache.cxf</groupId>
	<artifactId>cxf-codegen-plugin</artifactId>
	<version>3.2.5</version>
	<executions>
		<execution>
			<id>generate-sources</id>
			<phase>generate-sources</phase>
			<configuration>
				<!--代码生成的位置,不存在时会自动创建-->
				<!--生成到当前项目下-->
				<!--<sourceRoot>${project.basedir}/src/main/java</sourceRoot>-->
				<!--生成到指定目录下-->
				<sourceRoot>E:/temp/webservice/cxf-codegen-plugin2</sourceRoot>
				<!--下面wsdl如果是本地文件,则默认会扫描下面wsdl文件所属目录下的全部 *.wsdl 文件,而不仅仅是指定的文件-->
				<!--设置为true表示禁用扫描,只生成指定的xxx.wsdl文件-->
				<disableDirectoryScan>true</disableDirectoryScan>
				<wsdlOptions>
					<wsdlOption>
						<!--指定需要生成的wsdl文件,可以是本地文件,也可以是在线地址-->
						<wsdl>src/main/resources/wsdl/userService.wsdl</wsdl>
						<!--<wsdl>http://localhost:8080/webservice/userService?wsdl</wsdl>-->
					</wsdlOption>
				</wsdlOptions>
			</configuration>
			<goals>
				<goal>wsdl2java</goal>
			</goals>
		</execution>
	</executions>
</plugin>

https://gitee.com/wangmx1993/web_app/blob/master/src/main/resources/wsdl

pom.xml · 汪少棠/web_app - Gitee.com

2、最后在命令行窗口执行命令:mvn generate-sources 即可自动生成。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐