我正在使用 WSDL 生成 Java 类,该 WSDL 导入并包含大量其他模式和 DTD,而这些模式和 DTD 又相互引用。 (这是臭名昭著的“标准”XTA2 V3 WSDL,仅举个例子)
我收到的错误消息如下所示:
[ERROR] 'NonEmptyStringType' is already defined
Zeile 17 von file:/C:/Users/itbc000257/Documents/projekte/km-tafe/src/main/resources/META-INF/wsdl/OSCI_MessageMetaData_V2.02.xsd
[ERROR] (related to above error) the first definition appears here
Zeile 12 von file:/C:/Users/itbc000257/Documents/projekte/km-tafe/src/main/resources/META-INF/wsdl/OSCI_MessageMetaData_V2.02.xsd
该错误是由架构导入引起的,其中一个架构使用相对路径引用
schemaLocation
,而其他架构则使用绝对 http URL。
OSCI2_02.xsd 使用相对的
schemaLocation
:
<xs:import namespace="http://www.osci.eu/ws/2014/10/transport"
schemaLocation="OSCI_MessageMetaData_V2.02.xsd"/>
XTA.wsdl、XTA-synchron.wsdl、XTA-Webservice-Datentypen.xsd、XTA-Webservice-Globale-Elemente.xsd 使用绝对
schemaLocation
URL:
<xsd:import namespace="http://www.osci.eu/ws/2014/10/transport"
schemaLocation="http://www.osci.eu/ws/2014/10/transport/OSCI_MessageMetaData_V2.02.xsd"/>
来自 jaxb-ri 的 xjc 中存在一个长期存在的 bug,导致了此问题,并且后期的 Highsource 提出了修复方案,但从未将其纳入产品中。
就我而言,解决方法是下载所有相关架构,修复 OSCI2_02.xsd 架构导入以使用绝对 URL 并创建 jax-ws-catalog.xml,以便 wsimport 使用我修补的架构。
在下面找到我的设置。
模式文件的 WSDL 递归下载:
#!/bin/bash
# Anthony/Rabiaza
# 2018-02-31
# https://github.com/anthonyrabiaza/recursiveDownloader
# Patch by dschulten: load from absolute URLs and do not download already existing files to avoid endless loops
#wget parameters:
# -T 60: timeout of 60 sec
# -nv: non verbose
# -nc: skip downloads that would download to existing files
# --secure-protocol=TLSv1 --no-check-certificate: security related
wget_params="-T 60 -nv -nc --secure-protocol=TLSv1 --no-check-certificate
function help() {
echo "Please run this utility with the URL of the WSDL/XSD as argument"
echo -e "\tFor instance:"
echo -e "\t$0 http://192.168.0.96:8080/HelloWorld_WebServiceProject/wsdl/HelloWorld.wsdl"
}
function download() {
export filename=${1##*/}
if [ "$filename" == "" ];
then
echo -e "\tError for $1"
echo -ne "\t\t"
return -1
fi
echo -e "\tDownloading $filename"
echo -en "\t\twget -> "
wget $wget_params $1
echo ""
}
function getDependencies() {
export nbOccurrences=`grep -Po 'schemaLocation' $1 | wc -l`
echo "Grepped $nbOccurrences in $1"
if [ $nbOccurrences -gt 0 ];
then
export dependencies=`grep -Po 'schemaLocation="\K.*?(?=")' $1`
echo "$dependencies" | while read -r dependency
do
if [ ! -f ${dependency##*/} ] ; then
download $dependency
echo Filename: ${dependency##*/}
getDependencies ${dependency##*/}
fi
done
else
echo -e "\t\tNo more dependencies for $1"
fi
}
if [ $# -lt 1 ];
then help
exit -1
fi
currentDir="$PWD"
echo "Recursive Downloader"
echo "Command: $0"
echo "Parameters: $*"
echo ""
echo "Creating output folder"
mkdir -p output
cd output
export filename=${1##*/}
export serverPath=${1%/*}
echo "File to download $filename on $serverPath"
download $1
getDependencies $filename $serverPath
cd "$currentDir"
该脚本不下载 DTD,所以我还必须下载:
所有下载的文件都进入 src/main/resources/META-INF/wsdl。
同一文件夹中的以下 jax-ws-catalog.xml 告诉 wsimport 查找下载的文件,而不是从 Internet 下载它们:
<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog" prefer="system">
<system systemId="http://www.osci.eu/ws/2014/10/transport/OSCI_MessageMetaData_V2.02.xsd"
uri="OSCI_MessageMetaData_V2.02.xsd"/>
<system systemId="http://www.w3.org/2006/03/addressing/ws-addr.xsd" uri="ws-addr.xsd"/>
<system systemId="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
uri="oasis-200401-wss-wssecurity-secext-1.0.xsd"/>
<system systemId="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
uri="oasis-200401-wss-wssecurity-utility-1.0.xsd"/>
<system systemId="http://www.w3.org/2001/xml.xsd" uri="xml.xsd"/>
<system systemId="http://www.w3.org/TR/xmldsig-core/xmldsig-core-schema.xsd" uri="xmldsig-core-schema.xsd"/>
<system systemId="http://xoev.de/schemata/basisdatentypen/1_1/xoev-basisdatentypen.xsd"
uri="xoev-basisdatentypen.xsd"/>
<system systemId="http://www.osci.eu/ws/2014/10/transport/OSCI2_02.xsd" uri="OSCI2_02.xsd"/>
<system systemId="http://www.w3.org/2007/02/ws-policy.xsd" uri="ws-policy.xsd"/>
<system systemId="http://xoev.de/transport/xta/211/XTA-Webservice-Globale-Elemente.xsd"
uri="XTA-Webservice-Globale-Elemente.xsd"/>
<system systemId="http://xoev.de/transport/xta/211/xenc-schema.xsd" uri="xenc-schema.xsd"/>
<system systemId="http://xoev.de/transport/xta/211/XTA-Webservice-Exceptions.xsd"
uri="XTA-Webservice-Exceptions.xsd"/>
<system systemId="http://www.w3.org/2003/05/soap-envelope/" uri="soap-envelope.xsd"/>
<system systemId="http://www.w3.org/2001/XMLSchema.dtd" uri="XMLSchema.dtd"/>
</catalog>
这里是我的 jaxws-maven-plugin 定义,它使用 jakarta-ee 版本的插件(适用于 JAVA 8 以上),以及用于 jakarta-ee xml 的 patrodyne hisrc-basicjaxb-plugins 来生成 toString 等。 :
<plugin>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<goals>
<goal>wsimport</goal>
</goals>
</execution>
</executions>
<configuration>
<wsdlDirectory>src/main/resources/META-INF/wsdl</wsdlDirectory>
<wsdlFiles>
<wsdlFile>XTA.wsdl</wsdlFile>
</wsdlFiles>
<wsdlLocation>/META-INF/wsdl/XTA.wsdl</wsdlLocation>
<vmArgs>
<!-- nötig für file Zugriff auf datatypes.dtd im Dateisystem -->
<vmArg>-Djavax.xml.accessExternalDTD=all</vmArg>
</vmArgs>
<catalog>src/main/resources/META-INF/wsdl/jax-ws-catalog.xml</catalog>
<extension>true</extension>
<xjcArgs>
<xjcArg>-XfluentAPI</xjcArg>
<xjcArg>-XsimpleToString</xjcArg>
<xjcArg>-XsimpleEquals</xjcArg>
<xjcArg>-XsimpleHashCode</xjcArg>
</xjcArgs>
</configuration>
<dependencies>
<dependency>
<groupId>org.patrodyne.jvnet</groupId>
<artifactId>hisrc-basicjaxb-plugins</artifactId>
<version>2.1.1</version>
</dependency>
</dependencies>
</plugin>
最后,生成的类需要 jakarta.xml 依赖项:
<properties>
<jakarta.xml.version>4.0.1</jakarta.xml.version>
</properties>
<dependency>
<groupId>jakarta.xml.ws</groupId>
<artifactId>jakarta.xml.ws-api</artifactId>
<version>${jakarta.xml.version}</version>
</dependency>