使用wsimport生成Onvif WSDL代码时无服务定义报错问询
我之前踩过完全一样的坑,折腾了好一阵才搞定,给你一套亲测有效的步骤:
1. 给WSDL补上服务定义
Onvif的devicemgmt.wsdl本身只定义了接口和操作,没有包含**服务(Service)**节点,这就是wsimport报错的核心原因。你需要手动给下载好的本地WSDL文件添加服务声明:
找到文件末尾的</definitions>标签,在它前面插入这段XML(注意tds前缀要和WSDL里的命名空间保持一致,通常默认就是这个):
<service name="DeviceManagementService"> <port name="DeviceManagementPort" binding="tds:DeviceManagementBinding"> <soap:address location="http://your-onvif-device-ip/onvif/device_service"/> </port> </service>
这里的location填你实际设备的服务地址就行,暂时填个占位符也不影响代码生成。
2. 本地托管所有依赖XSD文件
在线拉取XSD经常会遇到网络超时、权限或者版本不一致的问题,建议把所有依赖的XSD文件(包括onvif.xsd、common.xsd,还有ver10 schema下的相关文件)都下载到本地,和WSDL放在同一个文件夹里,然后修改WSDL里的XSD引用路径:
比如原来的在线引用:
<xs:import namespace="http://www.onvif.org/ver10/schema" schemaLocation="https://www.onvif.org/ver10/schema/onvif.xsd"/>
改成本地相对路径:
<xs:import namespace="http://www.onvif.org/ver10/schema" schemaLocation="onvif.xsd"/>
要把WSDL里所有<xs:import>和<xs:include>的schemaLocation都改成本地路径,确保wsimport不用去在线拉取资源。
3. 执行正确的wsimport命令
现在用本地的WSDL文件来执行命令,不要再用在线URL了,命令格式如下:
wsimport -keep devicemgmt.wsdl -extension -Xnocompile
如果你的JDK版本是11及以上,wsimport被移到了jaxws-tools模块,需要先安装jaxws-tools再执行命令;用JDK8的话直接运行就行。
要是遇到命名空间冲突或者绑定问题,可以额外加一个binding.xml文件自定义绑定,命令改成:
wsimport -keep devicemgmt.wsdl -extension -Xnocompile -b binding.xml
4. 排查细节问题
如果还是报错,试试加-verbose参数看详细日志:
wsimport -keep devicemgmt.wsdl -extension -Xnocompile -verbose
从日志里能看到wsimport在处理哪个文件时出错,比如某个XSD下载不完整、命名空间拼写错误,针对性修复就行。
内容的提问来源于stack exchange,提问作者Crearo Rotar

