Invocar Web Services desde PL/SQL en Oracle

Sebas Enero 11th, 2008

El problema

Muchas veces nos vemos en la necesidad de invocar un Web Service directamente desde la base de datos.

La utilización de Java dentro de la base de datos no siempre es una opción disponible, así que tuve que buscar una solución que sólo utilizara código PL/SQL.

La solución

Podemos utilizar el package UTL_HTTP para hacer los request SOAP directamente al servidor destino, esto si bien es más complicado que utilizar las clases proxy, nos evita tener cargar Java en la base de datos.

La forma de invocar el package UTL_HTTP es la siguiente:

DECLARE
 
    req   UTL_HTTP.req := NULL;
    resp  UTL_HTTP.resp := NULL;
    respVal VARCHAR2(32000);
    reqXML VARCHAR2(32760);
 
BEGIN
 
/*Generamos un Request a la URL destino, el método debe ser POST */
    req := UTL_HTTP.begin_request('http://servidor/ConsultaClientes', 'POST');
 
/*Creamos un mensaje SOAP tal cual se define en el WSDL*/
 
reqXML := '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:m0="ConsultaClientes">
      <SOAP-ENV:Body>
            <m:ConsultaClientes xmlns:m="http://servidor/ConsultaClientes">
                  <m0:mensaje>
                        <m0:idcliente>C123452</m0:idcliente>
                  </m0:mensaje>
            </m:ConsultaClientes>
      </SOAP-ENV:Body>
</SOAP-ENV:Envelope>';
 
/*El contenido que enviamos es XML: */
    UTL_HTTP.set_header(req, 'Content-Type', 'text/xml');
 
/*Establecemos el SOAPAction a invocar: */
    UTL_HTTP.set_header(req, 'SOAPAction', '"rpc/http://servidor/ConsultaClientes"');
 
/*Indicamos en el header el tamaño del mensaje enviado: */
    UTL_HTTP.set_header(req, 'Content-Length', LENGTH(xml));
 
/*Escribimos el body del request */
    UTL_HTTP.write_text(req, xml);
 
/*Obtenemos la respuesta */
    resp := UTL_HTTP.get_response(req);
 
/*Cargamos en la variable respVal la devolución del servidor */
    UTL_HTTP.read_text(resp, respVal);
 
/*Finalizamos la conexión HTTP */
    UTL_HTTP.end_response(resp);
 
EXCEPTION
    WHEN UTL_HTTP.end_of_body THEN
      UTL_HTTP.end_response(resp);
END;
 
/

Conclusion

De esta manera rápida pudimos invocar un Web Service remoto utilizando PL/SQL, a partir de allí es posible convertir lo recibido en la variable respVal a un XMLTYPE para un mejor manejo.

Espero que les haya servido!!

Web social:
  • Digg
  • del.icio.us
  • Facebook
  • Google
  • Meneame
  • Technorati

Otros posts



8 Responses to “Invocar Web Services desde PL/SQL en Oracle”

  1. [...] cargar Java en la base de datos. La forma de invocar el package UTL_HTTP es la siguiente:Mas: http://slemos.com.ar/oracle/2008/01/invocar-web-services-desde-plsql-en-oracle/ [...]

  2. Marcoel 08 Abr 2008 a las 19:25

    Saludos, una consulta, tengo un problema al utilizar el snippet de codigo debido a que el WSDL que me genera mi webservice es muy distinto del suyo, no se si se deba a que mi WebService esta hecho en .NET, ademas dentro de su codigo no veo que ebn ningun lado se especifique la pagina ASMX para consumir el WerService, no es esto necesario?

    Una consulta adicional, el Web Service puede estar publicado en un servidor distinto a donde se encuentra la llamada del PL/SQL?

  3. Sebasel 09 Abr 2008 a las 11:18

    Marco, para armar el request te sugiero que copies el xml de request que arma algún programa que permita invocar Web Services, como por ejemplo XML Spy, una vez que tengas el request armado lo asignas a la variable reqXML.
    La página que tengas que invocar para el Web Service la pones en la linea:

    req := UTL_HTTP.begin_request(’http://servidor/ConsultaClientes’, ‘POST’);

    Cambiando ‘http://servidor/ConsultaClientes’ por la página destino que corresponda.

    Espero que te sirva,
    Saludos!

  4. Marcoel 09 Abr 2008 a las 14:50

    Estimado Sebas, realmente el problema en si a mi entender no es la invocacion, sino mas bien la generación del XML de la variable reqXML. Como indique anteriormente, el WSDL que me genera mi aplicacion de .NET es bastante distinto al del ejemplo por lo que pienso que quizas lo estoy armando de manera errónea.

    El WSDL de mi aplicacion es el siguiente:

    Por lo que no se exactamente que es lo que debo tomar para generar la cadena correcta del XML. Adicionalmente, se me ocurrió probar con el texto SOAP que se especifica dentro de la pagina de prueba del Webservice cuyo texto transcribo pero tampoco me funciono con este…

    int

    Que puedo hacer???

  5. Sebasel 11 Abr 2008 a las 12:04

    Marco, no me llegó en el comentario tu XML de prueba, pero cual es el error que obtienes?
    Si queres más ayuda te escribo un mail al que dejaste registrado en tu comentario.

    Saludos!

  6. RLeonel 01 May 2008 a las 15:08

    Estimados,

    Estuve en el mismo problema hace poco, y me parece una buena solucion,

    Pero si estan con oracle 10 (creo que desde el 9 en realidad)
    hay un Pk mas util, el UTL_DBWS, es mas sencillo para los webservices,
    y el problema mas comun es solo setear el proxy, te mando una pag con la referencia, fuera de ello todo me fue de maravilla!

    Espero les sirva!

    http://www.oracle-base.com/articles/10g/utl_dbws10g.php

    y para setear el proxy, es casi igual que en el utl_http

  7. Juanel 10 Jun 2008 a las 19:00

    Help !!!..

    Tengo mi archivo WSDL.. ahora quiero publicarlo desde un PL/SQL,
    Quiero echar andar este ejemplo… me manda un error en la linea sig:

    UTL_HTTP.set_header(req, ‘Content-Length’, LENGTH(xml));

    como lo hago funcionar para poder replicar lo mismo en mi caso.

    Saludos

  8. Sebasel 13 Jun 2008 a las 11:42

    Juan, que error te manda? podrías explicar un poco mas como estas armando la variable XML?

    Saludos!!

Trackback URI | Comments RSS

Deje su comentario