Creando un Web service en Oracle 10g, 11g y 12c.

Si necesitamos crear un web service en Oracle (desde la 10g hasta la 12c) necesitaremos realizar varios pasos.

Como primer requisito accederemos a la bbdd como SYS y realizaremos los siguientes pasos:

1-Creamos un usuario TEST que tendrá (para este caso y para evitar problemas de acceso) todos los privilegios posibles:

CREATE USER TEST
  IDENTIFIED BY TEST
  DEFAULT TABLESPACE USERS
  TEMPORARY TABLESPACE TEMP
  PROFILE DEFAULT
  ACCOUNT UNLOCK;
  -- 2 Roles for TEST
  GRANT CONNECT TO TEST WITH ADMIN OPTION;
  GRANT DBA TO TEST WITH ADMIN OPTION;
  ALTER USER TEST DEFAULT ROLE ALL;
  -- 22 System Privileges for TEST
  GRANT ALTER USER TO TEST;
  GRANT CREATE ANY INDEX TO TEST;
  GRANT CREATE ANY SYNONYM TO TEST;
  GRANT CREATE ANY TABLE TO TEST;
  GRANT CREATE ANY TRIGGER TO TEST;
  GRANT CREATE ANY VIEW TO TEST;
  GRANT CREATE SYNONYM TO TEST;
  GRANT CREATE TABLE TO TEST;
  GRANT CREATE TRIGGER TO TEST;
  GRANT CREATE USER TO TEST;
  GRANT DELETE ANY TABLE TO TEST;
  GRANT DROP ANY INDEX TO TEST;
  GRANT DROP ANY SYNONYM TO TEST;
  GRANT DROP ANY TABLE TO TEST;
  GRANT DROP ANY TRIGGER TO TEST;
  GRANT DROP ANY VIEW TO TEST;
  GRANT EXECUTE ANY PROCEDURE TO TEST WITH ADMIN OPTION;
  GRANT GRANT ANY PRIVILEGE TO TEST WITH ADMIN OPTION;
  GRANT INSERT ANY TABLE TO TEST;
  GRANT SELECT ANY TABLE TO TEST WITH ADMIN OPTION;
  GRANT UNLIMITED TABLESPACE TO TEST WITH ADMIN OPTION;
  GRANT UPDATE ANY TABLE TO TEST;
  -- 1 Tablespace Quota for TEST
  ALTER USER TEST QUOTA UNLIMITED ON USERS;
  -- 7 Object Privileges for TEST
    GRANT EXECUTE ON SYS.DBMS_NETWORK_ACL_ADMIN TO TEST;
    GRANT EXECUTE ON SYS.SYS_PLSQL_4D9DBC49_9_1 TO TEST WITH GRANT OPTION;
    GRANT EXECUTE ON SYS.UTL_HTTP TO TEST;
    GRANT EXECUTE ON SYS.UTL_INADDR TO TEST;
    GRANT EXECUTE ON SYS.UTL_SMTP TO TEST;
    GRANT EXECUTE ON SYS.UTL_TCP TO TEST;
    GRANT SELECT ON SYS.V_$SESSION TO TEST;

2-Para este ejemplo crearemos un DAD que nos dará acceso desde el navegador a los paquetes PL/SQL de la bbdd para el usuario TEST.

BEGIN
DBMS_EPG.create_dad (
dad_name => 'xml_demo',
path     => '/xml_demo/*');
END;
/

BEGIN
DBMS_EPG.authorize_dad (
dad_name => 'xml_demo',
user     => 'TEST');
END;
/

3-Si tenemos problemas para acceder al contenido de la bbdd, podemos crear un ACL (permiso) para que el usuario TEST tenga privilegios de conexion local.

BEGIN
  dbms_network_acl_admin.create_acl('localhost1.xml', 'ACL for localhost', 'TEST', TRUE, 'connect');
  dbms_network_acl_admin.assign_acl('localhost1.xml', 'localhost');
END;
/
COMMIT
/

4-Ahora crearemos dos tablas, EMP y DEPT a partir de las tablas de ejemplo del usuario SCOTT.

CREATE TABLE test.emp AS SELECT * FROM scott.emp;
CREATE TABLE test.dept AS SELECT * FROM scott.dept;

Nota: Si al intentar crear las tablas nos devuelve un error al acceder al usuario SCOTT significa que el usuario está bloqueado, para desbloquearlo, ejecutamos el siguiente comando:

ALTER USER SCOTT IDENTIFIED BY SCOTT ACCOUNT UNLOCK;

5-También debemos configurar el puerto de escucha por el cual se realizarán las peticiones desde el navegador. Primero debemos ver si ya está configurado, para ello ejecutamos el siguiente comando:

SELECT DBMS_XDB.gethttpport FROM dual;

Si devuelve 0, no está configurado, caso contrario devolverá un valor como el que aparece a continuación, en este caso el puerto ya está configurado en el 8080:

GETHTTPPORT
-----------
       8080

SQL>

En caso de que el puerto esté a 0 con el siguiente comando podremos configurarlo:

EXEC DBMS_XDB.sethttpport(8080);

PL/SQL procedure successfully completed.

SQL>

Ahora bien, como ya tenemos todo configurado (la parte de acceso), deberemos crear un paquete que nos permite acceder a los procedimientos almacenados en la bbdd, para ello ejecutamos el siguiente script:

6-Nos conectamos ya como TEST/TEST

7-Creamos el siguiente paquete junto con un procedimiento:

CREATE OR REPLACE PACKAGE xml_api AS

PROCEDURE get_emp_1 (p_empno  IN  emp.empno%TYPE DEFAULT NULL);

END xml_api;
/
SHOW ERRORS


CREATE OR REPLACE PACKAGE BODY xml_api AS

PROCEDURE error_page (p_message IN VARCHAR2);

PROCEDURE get_emp_1 (p_empno  IN  emp.empno%TYPE DEFAULT NULL) IS
BEGIN
  OWA_UTIL.mime_header('text/xml');
  HTP.print('');
  HTP.print('');

  FOR cur_rec IN (SELECT empno, ename, job FROM emp WHERE p_empno IS NULL OR empno = p_empno) LOOP
  HTP.print(
    ''
    || '' || cur_rec.empno || ''
    || '' || DBMS_XMLGEN.convert(cur_rec.ename) || ''
    || '' || DBMS_XMLGEN.convert(cur_rec.job) || ''
    || '
');  END LOOP;
  HTP.print('
');EXCEPTION
  WHEN OTHERS THEN
     error_page(SQLERRM);
END get_emp_1;


PROCEDURE error_page (p_message IN VARCHAR2) AS
BEGIN
  OWA_UTIL.mime_header('text/xml');
  HTP.print(
       ''
    || ''
    || '  ' || DBMS_XMLGEN.convert(p_message) || ''
    || '
');END error_page;

END xml_api;
/
SHOW ERRORS

8-Una vez que hayamos creado el paquete y procedimiento y éste no contenga errores, podremos consultar los datos directamente en el navegador (IE, CHROME) accediendo mediante la siguiente dirección:

Nota: Como no hemos configurado un acceso anónimo, el navegador nos solicitará las credenciales de acceso, para acceder, debemos simplemente introducir el usuario y contraseña de TEST.

Consultando todos los datos de la tabla:

http://SERVIDOR:8080/xml_demo/xml_api.get_emp_1

Consultando los datos pero incluyendo como condición que solo muestre los datos de la empresa 7369:
http://SERVIDOR:8080/xml_demo/xml_api.get_emp_1?p_empno=7369


El resultado será algo similar a ésto para el primer ejemplo:


<emp_list>
<emp>
<empno>7369</empno>
<ename>SMITH</ename>
<job>CLERK</job>
</emp>
<emp>
<empno>7499</empno>
<ename>ALLEN</ename>
<job>SALESMAN</job>
</emp>
<emp>
<empno>7521</empno>
<ename>WARD</ename>
<job>SALESMAN</job>
</emp>
<emp>
<empno>7566</empno>
<ename>JONES</ename>
<job>MANAGER</job>
</emp>
<emp>
<empno>7654</empno>
<ename>MARTIN</ename>
<job>SALESMAN</job>
</emp>
<emp>
<empno>7698</empno>
<ename>BLAKE</ename>
<job>MANAGER</job>
</emp>
....
</emp_list>


Mientras que si accedemos con el filtro tendremos solo este otro resultado:

<emp_list>
<emp>
<empno>7369</empno>
<ename>SMITH</ename>
<job>CLERK</job>
</emp>
</emp_list>


Espero que les resulte útil.

Salu2.

Share on Google Plus
    Blogger Comment

2 comentarios:

Ajedrez novatos dijo...

EXCELENTE, mejor explicado, ya lo voy a crear

Claudio G dijo...

Hola Como estas !!
Muy bueno tu ejemplo, muy claro, lo probe y tengo algun problema.
Cuando tipeo la url me responde :

No se puede acceder a este sitio web La página ha rechazado la conexión.
Desde ya muchas gracias.