Я пытаюсь создать заглушки Java для новой сторонней службы. Раньше это работало без проблем, но недавно они добавили новый метод verifyDataExistence
и wsdl2java
произошла ошибка со следующей ошибкой (настоящие имена были изменены):
Loading FrontEnd jaxws ...
Loading DataBinding jaxb ...
wsdl2java -verbose -b jaxb-bindings.xml -client -d src https://othercompany.com/SOAP/TheirService/Services?wsdl
wsdl2java - Apache CXF 3.5.5
Jan 06, 2024 1:22:55 PM org.apache.cxf.wsdl11.WSDLServiceBuilder checkForWrapped
INFO: Operation {urn:PegaRULES:SOAP:TheirService:Services}GetList cannot be unwrapped, input message must reference global element declaration with same localname as operation
Jan 06, 2024 1:22:55 PM org.apache.cxf.wsdl11.WSDLServiceBuilder checkForWrapped
INFO: Operation {urn:PegaRULES:SOAP:TheirService:Services}HandleInfo cannot be unwrapped, input message must reference global element declaration with same localname as operation
WSDLToJava Error: Parameter: theirData already exists for method verifyDataExistence but of type com.othercompany.soap.myservice.services.VerifyDataExistenceType.TheirData instead of com.mycompany.soap.theirservice.services.VerifyDataExistenceResponseType.TheirData. Use a JAXWS/JAXB binding customization to rename the parameter.
org.apache.cxf.tools.common.ToolException: Parameter: theirData already exists for method verifyDataExistence but of type com.othercompany.soap.myservice.services.VerifyDataExistenceType.TheirData instead of com.othercompany.soap.myservice.services.VerifyDataExistenceResponseType.TheirData. Use a JAXWS/JAXB binding customization to rename the parameter.
at org.apache.cxf.tools.common.model.JavaMethod.addParameter(JavaMethod.java:178)
at org.apache.cxf.tools.wsdlto.frontend.jaxws.processor.internal.ParameterProcessor.addParameter(ParameterProcessor.java:130)
at org.apache.cxf.tools.wsdlto.frontend.jaxws.processor.internal.ParameterProcessor.processWrappedAbstractOutput(ParameterProcessor.java:482)
at org.apache.cxf.tools.wsdlto.frontend.jaxws.processor.internal.ParameterProcessor.processWrappedOutput(ParameterProcessor.java:360)
at org.apache.cxf.tools.wsdlto.frontend.jaxws.processor.internal.ParameterProcessor.buildParamModelsWithoutOrdering(ParameterProcessor.java:651)
at org.apache.cxf.tools.wsdlto.frontend.jaxws.processor.internal.ParameterProcessor.process(ParameterProcessor.java:88)
at org.apache.cxf.tools.wsdlto.frontend.jaxws.processor.internal.OperationProcessor.processMethod(OperationProcessor.java:141)
at org.apache.cxf.tools.wsdlto.frontend.jaxws.processor.internal.OperationProcessor.process(OperationProcessor.java:62)
at org.apache.cxf.tools.wsdlto.frontend.jaxws.processor.internal.PortTypeProcessor.process(PortTypeProcessor.java:156)
at org.apache.cxf.tools.wsdlto.frontend.jaxws.processor.WSDLToJavaProcessor.wsdlDefinitionToJavaModel(WSDLToJavaProcessor.java:83)
at org.apache.cxf.tools.wsdlto.frontend.jaxws.processor.WSDLToJavaProcessor.process(WSDLToJavaProcessor.java:60)
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.processWsdl(WSDLToJavaContainer.java:274)
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.execute(WSDLToJavaContainer.java:156)
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.execute(WSDLToJavaContainer.java:402)
at org.apache.cxf.tools.common.toolspec.ToolRunner.runTool(ToolRunner.java:105)
at org.apache.cxf.tools.wsdlto.WSDLToJava.run(WSDLToJava.java:113)
at org.apache.cxf.tools.wsdlto.WSDLToJava.run(WSDLToJava.java:86)
at org.apache.cxf.tools.wsdlto.WSDLToJava.main(WSDLToJava.java:184)
Вот wsdl:
<wsdl:definitions
targetNamespace = "urn:PegaRULES:SOAP:TheirService:Services">
<wsdl:types>
<xsd:schema>
<xsd:import schemaLocation = "Services.xsd1.xsd"
namespace = "urn:PegaRULES:SOAP:TheirService:Services" />
</xsd:schema>
</wsdl:types>
<wsdl:message name = "GetList">
<wsdl:part name = "GetListRequest"
element = "xsns:GetListRequest" />
</wsdl:message>
<wsdl:message name = "GetListResponse">
<wsdl:part name = "GetListResponse"
element = "xsns:GetListResponse" />
</wsdl:message>
<wsdl:message name = "HandleInfo">
<wsdl:part name = "HandleInfoRequest"
element = "xsns:HandleInfoRequest" />
</wsdl:message>
<wsdl:message name = "HandleInfoResponse">
<wsdl:part name = "HandleInfoResponse"
element = "xsns:HandleInfoResponse" />
</wsdl:message>
<wsdl:message name = "VerifyDataExistence">
<wsdl:part name = "VerifyDataExistence"
element = "xsns:VerifyDataExistence" />
</wsdl:message>
<wsdl:message name = "VerifyDataExistenceResponse">
<wsdl:part name = "VerifyDataExistenceResponse"
element = "xsns:VerifyDataExistenceResponse" />
</wsdl:message>
<wsdl:portType name = "ServicesType">
<wsdl:operation name = "GetList">
<wsdl:input name = "GetListRequest"
message = "ns0:GetList" />
<wsdl:output name = "GetListResponse"
message = "ns0:GetListResponse" />
</wsdl:operation>
<wsdl:operation name = "HandleInfo">
<wsdl:input name = "HandleInfoRequest"
message = "ns0:HandleInfo" />
<wsdl:output name = "HandleInfoResponse"
message = "ns0:HandleInfoResponse" />
</wsdl:operation>
<wsdl:operation name = "VerifyDataExistence">
<wsdl:input name = "VerifyDataExistenceRequest"
message = "ns0:VerifyDataExistence" />
<wsdl:output name = "VerifyDataExistenceResponse"
message = "ns0:VerifyDataExistenceResponse" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name = "ServicesBindingSOAP"
type = "ns0:ServicesType">
<soap11:binding
transport = "http://schemas.xmlsoap.org/soap/http" style = "document" />
<wsdl:operation name = "GetList">
<soap11:operation
soapAction = "urn:PegaRULES:SOAP:TheirService:Services#GetList"
style = "document" />
<wsdl:input name = "GetListRequest">
<soap11:body use = "literal" />
</wsdl:input>
<wsdl:output name = "GetListResponse">
<soap11:body use = "literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name = "HandleInfo">
<soap11:operation
soapAction = "urn:PegaRULES:SOAP:TheirService:Services#HandleInfo"
style = "document" />
<wsdl:input name = "HandleInfoRequest">
<soap11:body use = "literal" />
</wsdl:input>
<wsdl:output name = "HandleInfoResponse">
<soap11:body use = "literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name = "VerifyDataExistence">
<soap11:operation
soapAction = "urn:PegaRULES:SOAP:TheirService:Services#VerifyDataExistence"
style = "document" />
<wsdl:input name = "VerifyDataExistenceRequest">
<soap11:body use = "literal" />
</wsdl:input>
<wsdl:output name = "VerifyDataExistenceResponse">
<soap11:body use = "literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name = "ServicesBindingSOAP12"
type = "ns0:ServicesType">
<soap12:binding
transport = "http://schemas.xmlsoap.org/soap/http" style = "document" />
<wsdl:operation name = "GetList">
<soap12:operation
soapAction = "urn:PegaRULES:SOAP:TheirService:Services#GetList"
soapActionRequired = "false" style = "document" />
<wsdl:input name = "GetRequest">
<soap12:body use = "literal" />
</wsdl:input>
<wsdl:output name = "GetListResponse">
<soap12:body use = "literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name = "HandleInfo">
<soap12:operation
soapAction = "urn:PegaRULES:SOAP:TheirService:Services#HandleInfo"
soapActionRequired = "false" style = "document" />
<wsdl:input name = "HandleInfoRequest">
<soap12:body use = "literal" />
</wsdl:input>
<wsdl:output name = "HandleInfoResponse">
<soap12:body use = "literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name = "VerifyDataExistence">
<soap12:operation
soapAction = "urn:PegaRULES:SOAP:TheirService:Services#VerifyDataExistence"
soapActionRequired = "false" style = "document" />
<wsdl:input name = "VerifyDataExistenceRequest">
<soap12:body use = "literal" />
</wsdl:input>
<wsdl:output name = "VerifyDataExistenceResponse">
<soap12:body use = "literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name = "ServicesService">
<wsdl:port name = "ServicesPortSOAP"
binding = "ns0:ServicesBindingSOAP">
<soap11:address
location = "https://192.168.1.2:1234/one/SomeServlet/SOAP/TheirService/Services" />
</wsdl:port>
<wsdl:port name = "ServicesPortSOAP12"
binding = "ns0:ServicesBindingSOAP12">
<soap12:address
location = "https://192.168.1.2:1234/one/SomeServlet/SOAP/TheirService/Services" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
и отдельный файл схемы:
<schema elementFormDefault = "unqualified"
targetNamespace = "urn:PegaRULES:SOAP:TheirService:Services">
<complexType name = "GetListRequestType">
<sequence>
<element name = "AppId" type = "xsd:string" />
<element minOccurs = "0" name = "DataCode" type = "xsd:string" />
<element minOccurs = "0" name = "DepId" type = "xsd:string" />
</sequence>
</complexType>
<element name = "GetListRequest"
type = "tns:GetListRequestType" />
<complexType name = "GetListResponseType">
<sequence>
<element name = "Count" type = "xsd:string" />
<element name = "List">
<complexType>
<sequence>
<element maxOccurs = "unbounded" name = "Data">
<complexType>
<sequence>
<element name = "ItemNo" type = "xsd:string" />
<element name = "DataCode" type = "xsd:string" />
<element name = "Prefix" type = "xsd:string" />
<element name = "Year" type = "xsd:string" />
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
<element name = "ErrorList">
<complexType>
<sequence>
<element maxOccurs = "unbounded" name = "Error">
<complexType>
<sequence>
<element name = "Code" type = "xsd:string" />
<element name = "Desc" type = "xsd:string" />
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
<element name = "GetListResponse"
type = "nslt1:GetListResponseType" />
<element name = "HandleInfoRequest"
type = "tns:HandleInfoRequestType" />
<complexType name = "HandleInfoResponseType">
<sequence>
<element name = "TheirData">
<complexType>
<sequence>
<element name = "DataCode" type = "xsd:string" />
<element name = "Prefix" type = "xsd:string" />
<element name = "Year" type = "xsd:string" />
<element name = "ItemNo" type = "xsd:string" />
<element name = "HandlingStatus" type = "xsd:string" />
</sequence>
</complexType>
</element>
<element minOccurs = "0" name = "ErrorsList">
<complexType>
<sequence>
<element maxOccurs = "unbounded" name = "Error">
<complexType>
<sequence>
<element name = "Code" type = "xsd:string" />
<element name = "Desc" type = "xsd:string" />
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
<element name = "HandleInfoResponse"
type = "nslt1:HandleInfoResponseType" />
<complexType name = "VerifyDataExistenceType">
<sequence>
<element name = "AppId" type = "xsd:string" />
<element name = "TheirData">
<complexType>
<sequence>
<element name = "DataCode" type = "xsd:string" />
<element name = "Prefix" type = "xsd:string" />
<element minOccurs = "0" name = "Year" type = "xsd:string" />
<element name = "ItemNo" type = "xsd:string" />
</sequence>
</complexType>
</element>
</sequence>
</complexType>
<element name = "VerifyDataExistence"
type = "tns:VerifyDataExistenceType" />
<complexType name = "VerifyDataExistenceResponseType">
<sequence>
<element name = "TheirData">
<complexType>
<sequence>
<element name = "ItemNo" type = "xsd:string" />
<element name = "DataCode" type = "xsd:string" />
<element name = "Prefix" type = "xsd:string" />
<element minOccurs = "0" name = "Year" type = "xsd:string" />
<element name = "DataExists" type = "xsd:string" />
<element name = "ProcessingCompleted" type = "xsd:string" />
</sequence>
</complexType>
</element>
<element minOccurs = "0" name = "ErrorList">
<complexType>
<sequence>
<element maxOccurs = "unbounded" name = "Error">
<complexType>
<sequence>
<element name = "Code" type = "xsd:string" />
<element name = "Desc" type = "xsd:string" />
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
<element name = "VerifyDataExistenceResponse"
type = "nslt1:VerifyDataExistenceResponseType" />
</schema>
Чтобы настроить генерацию, у меня уже есть jaxb-bindings.xml.
<jaxb:bindings version = "2.0" xmlns:jaxb = "http://java.sun.com/xml/ns/jaxb">
<jaxb:bindings>
<jaxb:globalBindings generateElementProperty = "false"/>
</jaxb:bindings>
</jaxb:bindings>
Согласно предложению об ошибке, я попытался использовать настройку привязки JAXWS/JAXB, чтобы переименовать параметр, например
<jaxb:bindings node = "//wsdl:message[@name='verifyDataExistenceRequest']/wsdl:part[@name='theirData']">
<jaxb:property name = "verifyExistenceRequestTheirData" />
</jaxb:bindings>
<jaxb:bindings node = "//wsdl:message[@name='verifyDataExistenceResponse']/wsdl:part[@name='theirData']">
<jaxb:property name = "verifyExistenceResponseTheirData" />
</jaxb:bindings>
Но это не работает, поскольку определение типовverifyDataExistenceRequest иverifyDataExistenceResponse находится в отдельном файле схемы xml https://othercompany.com/SOAP/TheirService/Services.xsd1.xsd
Также я пытался поиграть с атрибутом schemaLocation
, но ничего не получилось.
Буду признателен за любые идеи, как заставить это работать. Спасибо
Нет необходимости в настройке jaxb-bindings.xml
Достаточно просто добавить дополнительный параметр -autoNameResolution
к WSDLTOJava
.
Например. Задача gradle может выглядеть так:
task generateFromWsdl(type: JavaExec) {
main = 'org.apache.cxf.tools.wsdlto.WSDLToJava'
classpath = configurations.jaxb
args '-verbose', '-client', '-d', 'src/main/java', '-b', "$projectDir/src/jaxb/resources/jaxb-bindings.xml", "-suppress-generated-date", "-autoNameResolution", "$projectDir/src/jaxb/resources/${myWsdl}"
}
Более подробная информация: https://cxf.apache.org/docs/wsdl-to-java.html