Apache CXF 4.0.3导入XSD到WSDL时目标命名空间报错
Apache CXF 4.0.3 wsdl2java导入XSD报错问题分析
问题场景
使用Apache CXF 4.0.3的wsdl2java工具处理第三方WSDL文件时出现报错,该文件在旧版CXF中可正常导入。
简化后的WSDL内容
<?xml version="1.0" encoding="UTF-8"?> <definitions xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="https://webservices.sabre.com/websvc"> <types> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:import namespace="http://schemas.xmlsoap.org/ws/2002/12/secext" schemaLocation="wsse.xsd"/> </xsd:schema> </types> </definitions>
关联的wsse.xsd内容
<?xml version="1.0" encoding="UTF-8"?> <xs:schema targetNamespace="http://schemas.xmlsoap.org/ws/2002/12/secext" xmlns:xs="http://www.w3.org/2001/XMLSchema"> </xs:schema>
执行的wsdl2java命令
./wsdl2java -encoding UTF-8 -d /project/src/main/java -b "file:/project/src/main/resources/schema/custom-bindings/globalbinding.xjb" -p "=org.a.b.c" -suppress-generated-date -wsdlLocation classpath:schema/wsdl/sample.wsdl -verbose file:/project/src/main/resources/schema/wsdl/sample.wsdl
报错信息
org.apache.cxf.tools.common.ToolException:
file:///apache-cxf-4.0.3/bin/ [1,132]: the
target namespace of the imported schema "" doesn't agree with the
expected value "http://schemas.xmlsoap.org/ws/2002/12/secext
问题原因
核心原因是wsdl2java无法正确定位到wsse.xsd文件,导致解析时识别到的XSD目标命名空间为空,与WSDL中导入声明的命名空间不匹配:
- WSDL中
schemaLocation使用相对路径wsse.xsd,但执行wsdl2java时的工作目录是apache-cxf-4.0.3/bin,工具会优先在该目录下查找XSD,找不到则解析出空内容,进而导致目标命名空间识别失败。 - CXF 4.x基于JAXB 3.x,对XML Schema的路径解析逻辑比旧版更严格,旧版可能自动从WSDL所在目录查找依赖资源,新版则需要明确指定搜索路径。
解决方法
1. 调整XSD文件位置
将wsse.xsd放到WSDL所在的目录(/project/src/main/resources/schema/wsdl/),工具即可通过相对路径找到它。
2. 指定schema搜索路径
在wsdl2java命令中添加-classpath参数,指定包含XSD文件的目录:
./wsdl2java -encoding UTF-8 -d /project/src/main/java -b "file:/project/src/main/resources/schema/custom-bindings/globalbinding.xjb" -p "=org.a.b.c" -suppress-generated-date -wsdlLocation classpath:schema/wsdl/sample.wsdl -verbose -classpath /project/src/main/resources/schema/wsdl/ file:/project/src/main/resources/schema/wsdl/sample.wsdl
3. 使用XML Catalog映射
创建一个catalog文件(比如catalog.xml),将命名空间映射到XSD的绝对路径:
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog"> <uri name="http://schemas.xmlsoap.org/ws/2002/12/secext" uri="file:/project/src/main/resources/schema/wsdl/wsse.xsd"/> </catalog>
然后在命令中添加-catalog参数指定该文件:
./wsdl2java -encoding UTF-8 -d /project/src/main/java -b "file:/project/src/main/resources/schema/custom-bindings/globalbinding.xjb" -p "=org.a.b.c" -suppress-generated-date -wsdlLocation classpath:schema/wsdl/sample.wsdl -verbose -catalog file:/project/src/main/resources/catalog.xml file:/project/src/main/resources/schema/wsdl/sample.wsdl
4. 修改WSDL中的schemaLocation为绝对路径
如果允许临时修改第三方WSDL,将schemaLocation改为XSD的绝对路径:
<xsd:import namespace="http://schemas.xmlsoap.org/ws/2002/12/secext" schemaLocation="file:/project/src/main/resources/schema/wsdl/wsse.xsd"/>
内容的提问来源于stack exchange,提问作者Tim
相关产品推荐
相关产品推荐

