jueves, 29 de julio de 2021

[JD Edwards - BSSV] Integración JDE - Salesforce: Crear proxy paquete JAVA con WSIMPORT

 Hola amigos,

Recientemente he realizado una integración de JDE con Salesforce Cloud, a través de BSSV tanto de entrada como de salida con Soap. Salesforce utiliza Apex para las integraciones.

Integración JDE - Salesforce

Uno de los problemas principales que me encontré fue al generar el proxy client, ya que el WSDL de Organization que se genera tiene una gran cantidad de métodos (éste servicio es el principal, y se utiliza para todo lo relacionado con el acceso: login, logout, sessions, userinfo, etc), y además al generar el proxy client en JDeveloper 12c (12.2.1.3.0) daba errores por conflictos en los namespaces.

Así que, decidí utilizar un camino alternativo, utilizando la herramienta de JAVA wsimport el cual a partir del archivo o dirección WSDL nos generará un paquete java .jar con las clases y métodos del servicio, el cual podremos importar a nuestro proyecto como una librería externa y trabajar cómodamente.

Podéis encontrar mucha información acerca del uso de ésta herramienta java:

https://docs.oracle.com/javase/7/docs/technotes/tools/share/wsimport.html

https://www.ibm.com/support/knowledgecenter/es/SSEQTP_9.0.5/com.ibm.websphere.base.doc/ae/twbs_jaxwsclientfromwsdl.html

https://www.ibm.com/support/knowledgecenter/es/SSEQTP_9.0.5/com.ibm.websphere.base.doc/ae/rwbs_wsimport.html

https://mkyong.com/webservices/jax-ws/jax-ws-wsimport-tool-example/

http://chuwiki.chuidiang.org/index.php?title=Ejemplo_sencillo_de_web_service_con_jax-ws


Y más específicos para servicios de Salesforce:

https://stackoverflow.com/questions/2322953/jax-ws-adding-soap-headers

https://udby.com/archives/132

Os recomiendo, que la versión java que utilicéis para wsimport sea la misma que utilice la versión del JDeveloper configurado para vuestro JDE (esto podréis hacerlo directamente con el ejecutable de la versión java instalado o añadiendo la ruta de la versión java sobre el PATH del sistema operativo).


Ejemplo ejecución:

wsimport -b bindings.xjb -keep -B-XautoNameResolution -XadditionalHeaders -Xdebug OrganizationDEV.wsdl -clientjar SalesForceOrganizationDEVWSDLConnector.jar 

Donde

wsimport: comando java para la generación de clases a partir de wsdl

-b: expecifica archivos de enlace jaxws/jaxb o esquemas adicionales

bindings.xjb: archivo de enlace o esquemas adicionales

-keep: mantiene los archivos generados

-B-XautoNameResolution: instrucción de JAXB para automáticamente resolver conflictos de nombres

-XadditionalHeaders: genera parámetros de cabecera en los métodos de la peticiones

-Xdebug: imprime la información de depuración

OrganizationDEV.wsdl: archivo wsdl con la información del servicio

-clientjar: crea el archivo jar de los artefactos generados junto con los metadatos WSDL necesarios para llamar al servicio web.

SalesForceOrganizationDEVWSDLConnector.jar: archivo jar a generar con todas las clases java y wsdl para importar al proyecto.

El archivo bindings.xjb dependerá de los namespaces y transformaciones a realizar.

bindings.xjb

<?xml version="1.0" encoding="UTF-8"?>

<bindings

    wsdlLocation="wsdlcalidad.wsdl"

    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"

    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema"

    xmlns="http://java.sun.com/xml/ns/jaxws">

    <bindings node="//xsd:schema[@targetNamespace='urn:sobject.enterprise.soap.sforce.com']">

      <jaxb:globalBindings generateElementProperty="false" underscoreBinding="asCharInWord"/>

    </bindings>

</bindings>


Otro ejemplo:

<?xml version="1.0" encoding="UTF-8"?>

<bindings

    wsdlLocation="INTProducto_JDE.wsdl"

    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"

    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema"

    xmlns="http://java.sun.com/xml/ns/jaxws">

    <bindings node="//xsd:schema[@targetNamespace='http://soap.sforce.com/schemas/class/INTProducto_JDE']">

      <jaxb:globalBindings generateElementProperty="false" underscoreBinding="asCharInWord"/>

  <jaxb:schemaBindings>

        <jaxb:nameXmlTransform>

          <jaxb:typeName suffix="Type" />

        </jaxb:nameXmlTransform>

      </jaxb:schemaBindings>

    </bindings>

    <bindings node="//xsd:schema[@targetNamespace='http://soap.sforce.com/schemas/class/INTResponse']">

      <jaxb:globalBindings generateElementProperty="false" underscoreBinding="asCharInWord"/>

  <jaxb:schemaBindings>

        <jaxb:nameXmlTransform>

          <jaxb:typeName suffix="Type" />

        </jaxb:nameXmlTransform>

      </jaxb:schemaBindings>

    </bindings>

    <enableWrapperStyle>false</enableWrapperStyle>

    <enableAsyncMapping>false</enableAsyncMapping>

</bindings>

Y por último, importar el archivo .jar al proyecto, añadirlo a las librerías para el despliegue y empezar a utilizar las clases y métodos para la llamada al servicio.

Espero os sea útil.

Un saludo.