Importando Wsdl2Apex con múltiples wsdl: parte en un wsdl: mensaje
Estoy intentando importar un WSDL en Salesforce que contiene mensajes de varias partes.
Los mensajes de varias partes no son compatibles con la herramienta wsdl2Apex. La solución alternativa sugerida es modificar el WSDL para generar una clase ápice y mantener la misma estructura XML de solicitud-respuesta.
Intenté comenzar con el embeddedAsync.init
método en el que agregué una clase adicional para envolver todos los mensajes de las partes. sin embargo, la llamada falla con una excepción
System.CalloutException: Web service callout failed: WebService returned a SOAP Fault: Unexpected element {http://webservice.embedded.server.qa.encoway.com/}init found. Expected {http://webservice.embedded.server.qa.encoway.com/}WebserviceSessionId. faultcode=soap:Client faultactor=
Soy nuevo en el mundo de las API de SOAP y me gustaría entender cómo se consume el WSDL multiparte en el ápice.
Un simple ejemplo sería de gran ayuda.
Aquí están el WSDL y el código generado en el que modifiqué el embeddedAsync.init
método: Código de muestra
Respuestas
Desafortunadamente, no creo que pueda usar wsdl2apex y el correspondiente WebServiceCallout.invoke()
para llamar a estos métodos multiparte.
Como ha observado, el init
mensaje se compone de 4 partes:
- ID de sesión
- taskId
- initContext
- callbackContext
Pero WebServiceCallout.invoke()
solo aceptará un único parámetro de solicitud como segundo argumento.
Es posible que pueda promover todas las partes menos una en encabezados según Importación de WSDL de direcciones de UPS en Apex , pero eso dependería de lo que espera el servicio web de destino.
Hay un par de desafíos con este WSDL :
- El
schema
define atargetNamespace
, pero omite elxmlns
atributo. - Hay varios elementos en el esquema que se definen como tipos complejos que tienen un elemento anidado también definido por un tipo complejo. Ej
AsyncActivateResult > activateResult
.
(1) se resolvió fácilmente agregando un xmlns
atributo en el esquema para que coincida con targetNamespace.
<xs:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://webservice.embedded.server.qa.backend.com/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" attributeFormDefault="unqualified" elementFormDefault="unqualified"
targetNamespace="http://webservice.embedded.server.qa.backend.com/"
xmlns="http://webservice.embedded.server.qa.backend.com/"
version="1.0">
(2) se resolvió extrayendo los elementos complexType anidados que los promueven a descendientes directos del esquema. Luego, los elementos usan el tipo resultante como referencia en lugar de intentar anidar complexType.
<!-- Created this complex type from the content of activateResult -->
<xs:complexType name="activateResultType">
<xs:complexContent>
<xs:extension base="tns:SaveResultType">
<xs:sequence>
<xs:element minOccurs="0" name="printedDocument" type="tns:ActivationAttachment"/>
<xs:element minOccurs="0" name="exportFormat" type="tns:ActivationAttachment"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="AsyncActivateResult">
<xs:complexType>
<xs:sequence>
<xs:element name="phase" type="xs:int"/>
<xs:element minOccurs="0" name="activateResult" type="activateResultType">
<!--<xs:complexType> has been un-nested -->
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
La clase de Apex resultante: webserviceEmbeddedServerQaBackendCo.cls