Services Web dans Oracle



Services Weblargement utilisĂ© pour l'intĂ©gration entre les composants d'un systĂšme ou entre diffĂ©rents systĂšmes. La popularitĂ© des services Web comme moyen d'intĂ©gration est due Ă  leur polyvalence, ainsi qu'Ă  leur facilitĂ© de mise en Ɠuvre et de dĂ©bogage. La polyvalence est associĂ©e au transfert de donnĂ©es via Internet et le protocole HTTP. Les services Web facilitent relativement la crĂ©ation d'intĂ©grations entre des composants Ă©crits dans diffĂ©rents langages qui s'exĂ©cutent sur diffĂ©rents systĂšmes d'exploitation et plates-formes. La simplicitĂ© de la mise en Ɠuvre des services Web est obtenue grĂące aux outils et composants intĂ©grĂ©s dans de nombreux IDE qui vous permettent de dĂ©velopper rapidement Ă  la fois le service Web (cĂŽtĂ© fournisseur) et le code nĂ©cessaire pour appeler le service cĂŽtĂ© client (cĂŽtĂ© client). Les services de dĂ©bogage sont simplifiĂ©s par l'utilisation de formats d'Ă©change de donnĂ©es lisibles par l'homme - XML ​​et JSON. Outre,Il existe de nombreux utilitaires pour les services de dĂ©bogage et de test, y compris la charge.

Dans cet article, nous examinerons plusieurs façons de créer des services Web directement à partir d'Oracle DBMS, c'est-à-dire sans utiliser d'outils tiers.

Contenu

Native Oracle XML DB Web Services
    
    
         Oracle XML DB HTTP server
         HTTP
         -
         Access List (ACL)
     -
    
Oracle REST Data Service
    
    
        
        
        
        
     1: POST-
         WS
        
        
         HTTP-
        
        
        CGI-
     2: ORDS
        
         ORDS
        
        
        
    

    Java Servlet
    Database Access Descriptor (PL/SQL Servlet)

Contexte


ÉlĂ©ments fournis: systĂšme d'information commercial d'un grand rĂ©seau de distribution (environ un millier de magasins de dĂ©tail), composĂ© de nombreux composants et sous-systĂšmes. À l'intĂ©rieur de chaque magasin, il y a un serveur principal - une base de donnĂ©es Oracle avec la logique mĂ©tier principale. Les nƓuds de caisse sont gĂ©rĂ©s par un logiciel distinct de leur base de donnĂ©es locale. Ce logiciel collecte pĂ©riodiquement les donnĂ©es du serveur principal (via WS SOAP) et rend les rĂ©sultats de la vente (Ă©change de fichiers).

Les progrĂšs ne se sont pas arrĂȘtĂ©s et de nouveaux Ă©quipements sont apparus dans les magasins. Les donnĂ©es de cet Ă©quipement doivent ĂȘtre pĂ©riodiquement envoyĂ©es au serveur principal de la boutique (pĂ©riode - toutes les quelques minutes), l'intĂ©gration doit nĂ©cessairement passer par le service Web, le message doit avoir un certain format, l'authentification n'est pas nĂ©cessaire. Nous avons examinĂ© les contrats d'Ă©change de donnĂ©es et dĂ©couvert que la technologie utilisĂ©e des services Web ne permettrait pas l'intĂ©gration du bĂątiment avec un tel Ă©quipement. Et la recherche d'une solution a commencĂ© ...

En consĂ©quence, plusieurs options pour la mise en Ɠuvre du service Web nĂ©cessaire ont Ă©tĂ© envisagĂ©es, jusqu'Ă  l'Ă©criture d'un composant distinct qui ouvrirait une fenĂȘtre pour la base de donnĂ©es Oracle pour la base de donnĂ©es Oracle: d'une part, il fournirait un service Web, d'autre part, il interagirait avec la base de donnĂ©es via JDBC. La difficultĂ© est que le nouveau composant, d'une part, devrait ĂȘtre installĂ© dans un millier de magasins, et, d'autre part, un autre lien serait apparu qu'il faudrait accompagner. Par consĂ©quent, la prioritĂ© Ă©tait toujours l'option d'implĂ©menter un service Web avec les outils intĂ©grĂ©s d'Oracle.

À la suite des recherches, nous avons trouvĂ© quatre façons que nous considĂ©rerons dans cet article:

  1. Services Web Oracle XML DB natifs
  2. Service de données Oracle REST
  3. Servlet Java
  4. Descripteur d'accÚs à la base de données (servlet PL / SQL)

Les deux premiÚres options seront examinées plus en détail. Les services Web Oracle XML DB natifs étaient initialement utilisés dans notre systÚme, c'est-à-dire qu'ils étaient hérités, pour ainsi dire. ORDS est devenu un remplacement pour cette technologie obsolÚte (malgré le fait que je devais encore travailler dur et installer ORDS dans un millier de magasins).

Deux autres méthodes - Java Servlet et PL / SQL Servlet - nous avons considéré avec ORDS lors de la recherche d'une alternative à Native Oracle WS, mais nous ne l'avons pas utilisée dans le projet. Par conséquent, nous ne considérerons pas ces approches en détail et nous limiterons à une brÚve référence.

L'article prĂ©sentera quelques exemples pratiques de mise en Ɠuvre de services Web avec des instructions qui aideront Ă  crĂ©er un service fonctionnel.

Services Web Oracle XML DB natifs


Capacités


Vous permet d'organiser l'accÚs à la base de données Oracle via HTTP à l'aide de WS SOAP (version 1.1):

  • SQL- XQuery- SOAP.
  • ( ).



  • - : , HTTP-.
  • - (WSDL), , -.
  • -. , — , — .
  • XML-. , , XML, - — Oracle . , WS- Oracle — , - .



  • WSDL , , - . — WSDL, WSDL , .
  • ( 50 ). , — , . , - — , , .

Il convient de noter que l'authentification est requise pour toutes les demandes au service Web (Ă  partir de la documentation : Authentification de base: Oracle XML DB prend en charge l'authentification de base, oĂč un client envoie le nom d'utilisateur et le mot de passe en texte clair dans l'en-tĂȘte d'autorisation). Dans Oracle, vous pouvez configurer l'accĂšs anonyme aux ressources du serveur via HTTP - Ă  l'aide de la configuration du serveur de protocole Oracle XML DB , mais en fait, cela ne fonctionne que pour les demandes GET, et l'authentification est requise pour les demandes POST. Étant donnĂ© que Native Oracle WS ne fonctionne que par le biais de requĂȘtes POST, il n'y a aucun moyen de configurer l'accĂšs anonyme pour cette technologie.

Personnalisation


Pour utiliser Native Oracle WS, vous aurez besoin de:

  1. Configurez le serveur HTTP intégré dans Oracle.
  2. Configurez l'accÚs à l'intérieur de la base de données Oracle (ouvrez le port HTTP).
  3. Créez une servlet.
  4. Configurez ACL (Access List).

Configurer le serveur HTTP Oracle XML DB


Le serveur HTTP devrait dĂ©jĂ  fonctionner par dĂ©faut, mais dans certains cas, une configuration d'Ă©coute supplĂ©mentaire peut ĂȘtre requise - en ajoutant le bloc suivant Ă  DESCRIPTION_LIST:

(DESCRIPTION=
  (ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=8080))(Presentation=HTTP)(Session=RAW)
)

AprÚs cela, vous devez redémarrer l'écouteur.

Configurer l'accĂšs HTTP


  1. VĂ©rification du port actuel pour HTTP.

    SELECT dbms_xdb.gethttpport() AS http_port FROM dual;

    Une valeur de "0" signifie que l'accÚs HTTP est désactivé.
  2. Configuration du port.

    BEGIN
        --    web-services
        dbms_xdb.setHttpPort(8080);
        COMMIT;
    END;
    /

Création d'une servlet pour un service Web


Pour que le service Web fonctionne, l'enregistrement du servlet est requis dans la configuration de la base de données.

Script pour créer un servlet
--   SYS
DECLARE
    l_servlet_name      VARCHAR2(32)  := 'orawsv';
BEGIN
    --   orawsv   Native Web Services
    DBMS_XDB.deleteServletMapping(l_servlet_name);
    DBMS_XDB.deleteServlet(l_servlet_name);
 
    DBMS_XDB.addServlet( NAME     => l_servlet_name
                       , LANGUAGE => 'C'
                       , DISPNAME => 'Oracle Query Web Service'
                       , DESCRIPT => 'Servlet for issuing queries as a Web Service'
                       , SCHEMA   => 'XDB');
 
    DBMS_XDB.addServletSecRole( SERVNAME => l_servlet_name
                              , ROLENAME => 'XDB_WEBSERVICES'
                              , ROLELINK => 'XDB_WEBSERVICES');
 
    DBMS_XDB.addServletMapping( PATTERN => '/orawsv/*'
                              , NAME    => l_servlet_name);
    COMMIT;
END;
/

Configurer la liste d'accĂšs


Pour accéder à Oracle via HTTP, vous devez ajouter des rÚgles dans la configuration du SGBD. Cela se fait à l'aide des utilitaires SGBD intégrés.

Pour configurer l'ACL, vous aurez besoin de:

  • script d'Ă©dition de la configuration de la base de donnĂ©es (ci-dessous);
  • schĂ©ma de base de donnĂ©es pour lequel la configuration est effectuĂ©e.

Autrement dit, le schĂ©ma de base de donnĂ©es pour lequel ACL est configurĂ© doit dĂ©jĂ  ĂȘtre crĂ©Ă©. Dans les exemples ci-dessous, il y aura des rĂ©fĂ©rences Ă  cette section, aux endroits oĂč vous devez crĂ©er de nouveaux schĂ©mas de base de donnĂ©es - pour eux, vous devrez configurer l'ACL.

Dans le schéma SYS, nous exécutons le script de configuration ACL:
--   SYS
DECLARE
    l_ws_user       VARCHAR2(32)  := 'WS_SOAP_TEST'; --    ,        WS
    l_acl           VARCHAR2(250) := 'acl_allow_all.xml';
    l_tmp           VARCHAR2(250);
BEGIN
    EXECUTE IMMEDIATE 'GRANT XDB_WEBSERVICES TO "'||l_ws_user||'"';
    EXECUTE IMMEDIATE 'GRANT XDB_WEBSERVICES_OVER_HTTP TO "'||l_ws_user||'"';
    EXECUTE IMMEDIATE 'GRANT XDB_WEBSERVICES_WITH_PUBLIC TO "'||l_ws_user||'"';
 
    --       PL/SQL 
    BEGIN
        dbms_network_acl_admin.drop_acl(acl => '/sys/acls/'||l_acl);
    EXCEPTION
        WHEN dbms_network_acl_admin.acl_not_found THEN
            NULL;
    END;
 
    --  ACL
    dbms_network_acl_admin.create_acl( acl         => l_acl
                                     , description => 'Allow all connections'
                                     , is_grant    => TRUE
                                     , start_date  => SYSTIMESTAMP
                                     , end_date    => NULL
                                     , principal   => 'SYS'
                                     , privilege   => 'connect');
 
    dbms_network_acl_admin.assign_acl( acl        => l_acl
                                     , host       => '*'
                                     , lower_port => NULL
                                     , upper_port => NULL);
 
    --    (resolve) 
    dbms_network_acl_admin.add_privilege( acl        => l_acl
                                        , principal  => l_ws_user
                                        , is_grant   => TRUE
                                        , privilege  => 'resolve'
                                        , POSITION   => NULL
                                        , start_date => SYSTIMESTAMP
                                        , end_date   => NULL);
 
    COMMIT;
END;
/

Il convient de noter tout de suite que la configuration ACL est requise lors de l'utilisation non seulement de Native Oracle WS, mais également de toutes les autres méthodes de création de services Web décrites dans cet article.

Exemple de service Web à l'aide d'une procédure par lots


Nous aurons besoin:

  • SchĂ©ma de base de donnĂ©es dans lequel se trouveront les objets de traitement des demandes de service Web.
  • Tableau de journalisation.
  • Package avec procĂ©dure / fonction.
  • Tout outil qui vous permet d'envoyer des demandes Web. Dans ce cas, l'application SOAP UI a Ă©tĂ© utilisĂ©e , mais vous pouvez choisir n'importe quel autre outil, jusqu'Ă  la ligne de commande.

Fonctionnalités:

  • Les paramĂštres de procĂ©dure doivent avoir des types simples ou d'objet. Sinon, la procĂ©dure ne sera pas perçue comme une mĂ©thode de service Web et ne sera pas incluse dans la liste des mĂ©thodes de service.
  • Pour implĂ©menter des structures complexes de donnĂ©es d'entrĂ©e ou de sortie, vous devez utiliser des types d'objets (les types de lots ne peuvent pas ĂȘtre utilisĂ©s).

Nous créons les objets de base de données nécessaires:

  1. Schéma WS_TEST:

    CREATE USER WS_SOAP_TEST IDENTIFIED BY ws_soap_test QUOTA 200M ON USERS;
    GRANT CREATE SESSION, RESOURCE TO ws_soap_test;

    Ajoutez immédiatement un nouveau schéma à l'ACL. Le script de la section précédente.
  2. Dans le nouveau schéma, créez une table pour la journalisation T_WS_REQ_LOG:

    CREATE TABLE T_WS_REQ_LOG
    (
      id_log      NUMBER GENERATED ALWAYS AS IDENTITY,
      message     VARCHAR2(2000),
      proc        VARCHAR2(128),
      dtm_request TIMESTAMP(6) DEFAULT SYSTIMESTAMP
    );
    COMMENT ON TABLE T_WS_REQ_LOG IS ' HTTP-';
    COMMENT ON COLUMN T_WS_REQ_LOG.id_log IS '';
    COMMENT ON COLUMN T_WS_REQ_LOG.message IS '';
    COMMENT ON COLUMN T_WS_REQ_LOG.proc IS '';
    COMMENT ON COLUMN T_WS_REQ_LOG.dtm_request IS '/ ';
  3. Package avec une procédure simple:

    
    CREATE OR REPLACE PACKAGE PK_NATIVE_WS_TEST IS
     
    PROCEDURE proc_simple
        ( a_id      INTEGER
        , a_data    VARCHAR2
        , o_result  OUT VARCHAR2
        );
     
    END PK_NATIVE_WS_TEST;
    /
    CREATE OR REPLACE PACKAGE BODY PK_NATIVE_WS_TEST IS
     
    PROCEDURE proc_simple
        ( a_id      INTEGER
        , a_data    VARCHAR2
        , o_result  OUT VARCHAR2
        )
    AS
    BEGIN
        INSERT INTO t_ws_req_log (message, proc)
        VALUES ('ID='||a_id||'; DATA='||a_data, 'proc_simple')
        RETURNING id_log INTO o_result;
    END proc_simple;
     
    END PK_NATIVE_WS_TEST;
    /

Le service Web le plus simple est crĂ©Ă© et prĂȘt Ă  l'emploi.

Pour accéder au service, vous devez utiliser l'URL au format suivant:

http://[server]:[port]/[servlet_name]/[DB_SCHEMA]/[WS_OBJ]?wsdl

OĂč:

[serveur] - nom de domaine ou adresse IP du serveur de base de données Oracle
[port] - port d'accÚs via HTTP spécifié dans la section "Configuration de l'accÚs via HTTP"
[nom_servlet] - nom du servlet spĂ©cifiĂ© dans la section "CrĂ©ation d'une servlet pour le Web service ”
[DB_SCHEMA] - nom du schéma de base de données (en majuscules)
[WS_OBJ] - nom du service (en majuscules), qui est égal au nom de l'objet de base de données, dans notre cas - le nom du package

Notez que l'URL est importante!

Exemple de lien:

http://my.server:8080/orawsv/WS_SOAP_TEST/PK_NATIVE_WS_TEST?wsdl

Si nous cliquons sur ce lien dans le navigateur, nous serons automatiquement créés sur la base de notre package WSDL:

Wsdl
<definitions name="PK_NATIVE_WS_TEST"
    targetNamespace="http://xmlns.oracle.com/orawsv/WS_SOAP_TEST/PK_NATIVE_WS_TEST"
    xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:tns="http://xmlns.oracle.com/orawsv/WS_SOAP_TEST/PK_NATIVE_WS_TEST"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
  <types>
    <xsd:schema targetNamespace="http://xmlns.oracle.com/orawsv/WS_SOAP_TEST/PK_NATIVE_WS_TEST"
     elementFormDefault="qualified">
      <xsd:element name="PROC_SIMPLEInput">
        <xsd:complexType>
            <xsd:sequence>
              <xsd:element name="A_DATA-VARCHAR2-IN" type="xsd:string"/>
              <xsd:element name="A_ID-NUMBER-IN" type="xsd:integer"/>
            </xsd:sequence>
          </xsd:complexType>
      </xsd:element>
 
      <xsd:element name="PROC_SIMPLEOutput">
        <xsd:complexType>
            <xsd:sequence>
              <xsd:element name="O_RESULT" type="xsd:string"/>
            </xsd:sequence>
          </xsd:complexType>
      </xsd:element>
   </xsd:schema>
  </types>
 
  <message name="PROC_SIMPLEInputMessage">
    <part name="parameters" element="tns:PROC_SIMPLEInput"/>
  </message>
 
  <message name="PROC_SIMPLEOutputMessage">
    <part name="parameters" element="tns:PROC_SIMPLEOutput"/>
  </message>
 
  <portType name="PK_NATIVE_WS_TESTPortType">
  <operation name="PROC_SIMPLE">
      <input message="tns:PROC_SIMPLEInputMessage"/>
      <output message="tns:PROC_SIMPLEOutputMessage"/>
    </operation>
  </portType>
 
  <binding name="PK_NATIVE_WS_TESTBinding"
           type="tns:PK_NATIVE_WS_TESTPortType">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="PROC_SIMPLE">
      <soap:operation
 soapAction="PROC_SIMPLE"/>
      <input>
        <soap:body parts="parameters" use="literal"/>
      </input>
      <output>
        <soap:body parts="parameters" use="literal"/>
      </output>
    </operation>
  </binding>
 
  <service name="PK_NATIVE_WS_TESTService">
    <documentation>Oracle Web Service</documentation>
    <port name="PK_NATIVE_WS_TESTPort" binding="tns:PK_NATIVE_WS_TESTBinding">
       <soap:address 
             location="http://******:8080/orawsv/WS_SOAP_TEST/PK_NATIVE_WS_TEST"/>
     </port>
  </service>
 
</definitions>

Pour tester le service, créez un nouveau projet SOAP dans l'interface utilisateur SOAP. En tant qu'URL, spécifiez l'adresse dans l'exemple ci-dessus.

À l'ouverture, Request 1nous voyons que le modĂšle de demande est dĂ©jĂ  gĂ©nĂ©rĂ© automatiquement par le WSDL spĂ©cifiĂ©.

Ajoutez immĂ©diatement l'autorisation de base pour la demande - le login et le mot de passe sont les mĂȘmes que lors de la connexion Ă  la base de donnĂ©es.



Exemple de demande et de réponse. Veuillez noter qu'une ligne a été ajoutée à la demande générée automatiquement <pk:O_RESULT-VARCHAR2-OUT/>. Le fait est qu'il y a un bogue dans Oracle 12c: les variables OUT ne sont pas ajoutées au WSDL pour Native Oracle WS).



Le résultat de l'appel est visible dans la table des journaux.



résultats


La technologie native Oracle XML DB Web Services peut ĂȘtre utilisĂ©e comme une solution industrielle Ă  condition qu'il n'y ait pas de charge importante sur ce service Web (une demande en quelques secondes). Cette option convient lorsque les consommateurs n'ont pas d'exigences strictes pour un service Web (ses attributs, structures de donnĂ©es, logique de traitement) et qu'il n'y a pas de contrat prĂ©dĂ©terminĂ© strict. Si vous devez crĂ©er un service Web selon un WSDL prĂ©dĂ©fini (comme dans notre cas avec un nouvel Ă©quipement), la technologie Native Oracle WS ne sera pas adaptĂ©e.

Service de données Oracle REST


À partir de la version 11.1, Oracle a introduit la prise en charge complĂšte de RESTful sous la forme d'un module distinct appelĂ© Oracle REST Data Service (ORDS).

ORDS est une application Java qui vous permet de crĂ©er une API RESTful pour une base de donnĂ©es Oracle Ă  l'aide de SQL et PL / SQL. C'est une alternative Ă  l'utilisation d'Oracle HTTP Server et de mod_plsql. En substance, ORDS est une interface HTTP entre le monde extĂ©rieur et une base de donnĂ©es Oracle. Cette interface vous permet de fermer les requĂȘtes HTTP entrantes Ă  n'importe quel objet de base de donnĂ©es - une table ou une procĂ©dure PL / SQL.

Il suffit d'installer, de configurer et d'exĂ©cuter ORDS pour la base de donnĂ©es requise. Le processus supplĂ©mentaire de crĂ©ation de services REST se rĂ©sume Ă  l'Ă©criture de code en PL / SQL (ou mĂȘme en cliquant dans l'IDE si le code est trop paresseux pour ĂȘtre Ă©crit).

Aucune licence supplémentaire n'est requise pour installer ORDS.

Exigences:

  • Java JDK 8 ou supĂ©rieur;
  • Oracle 11.1 ou version ultĂ©rieure (Oracle 11 XE Release 2 est Ă©galement pris en charge).

Plusieurs options de déploiement ORDS sont prises en charge:

  • mode autonome;
  • sur le serveur d'applications (Oracle WebLogic Server, Apache Tomcat).

Capacités


ORDS vous permet de:

  • Organisez l'accĂšs aux ressources dans un style RESTful.
  • CrĂ©ez une interaction dans le style "Appel de procĂ©dure distante" (interaction de style RPC).

En termes simples, avec l'aide d'ORDS, vous pouvez ouvrir l'accÚs via HTTP à certains objets de base de données - tables, procédures, fonctions, packages.

Dans le premier cas, nous avons affaire Ă  des ressources dans le sens oĂč elles sont comprises dans le style architectural RESTful. Chaque ressource est dĂ©finie par un URI unique et les opĂ©rations avec des ressources (CRUD - crĂ©er, lire, modifier, supprimer) sont dĂ©terminĂ©es par les opĂ©rations de la requĂȘte HTTP: PUT, POST, GET, DELETE. Par exemple, si la ressource est une entrĂ©e dans la table des employĂ©s, cette entrĂ©e sera disponible par un URI du formulaire:

GET https://server:port/ords/workspace/hr/employees/7369

Ici, le nom du schĂ©ma de base de donnĂ©es, le nom de la table et l'ID d'enregistrement dans la table sont indiquĂ©s dans l'URI. Ainsi, cette demande HTTP effectue en fait une opĂ©ration SELECT Ă  partir de la table spĂ©cifiĂ©e. Avec d'autres opĂ©rations (ajout, modification, suppression), le principe de communication est le mĂȘme: le chemin d'accĂšs Ă  la ressource est indiquĂ© dans l'URI, et des paramĂštres supplĂ©mentaires sont indiquĂ©s dans le corps de la demande, par exemple, des valeurs de champ pour insĂ©rer un enregistrement dans la table.

Dans le second cas, au lieu d'accĂ©der Ă  la ressource, un appel de procĂ©dure est directement utilisĂ©, qui peut tout faire de la mĂȘme maniĂšre que dans le premier cas (CRUD), ainsi que d'exĂ©cuter toute autre logique qui implĂ©mente le processus mĂ©tier nĂ©cessaire. Un appel de procĂ©dure Ă  partir d'un package peut ĂȘtre effectuĂ© Ă  l'aide d'une requĂȘte HTTP de ce format:

http://localhost:8080/ords/my_schema/my_pkg/MY_PROC

Les paramĂštres de la procĂ©dure sont transfĂ©rĂ©s dans le corps de la demande sous la forme de structures au format JSON {"param" : "value"}. La mĂȘme approche est utilisĂ©e lors de l'utilisation du WS Oracle natif, dĂ©crite ci-dessus, mais dans le cas des services REST, aucune restriction n'est imposĂ©e par le protocole SOAP.

avantages

  • Un mĂ©canisme flexible qui vous permet de mettre en Ɠuvre des services Web de toute complexitĂ©.
  • SimplicitĂ© de mise en Ɠuvre: pour transformer une procĂ©dure PL / SQL en service Web, vous devez exĂ©cuter seulement quelques commandes typiques. Et Ă  l'aide de SQL Developer, la crĂ©ation d'une API REST se transforme en un clic de souris avec un minimum d'Ă©criture de code.
  • La possibilitĂ© d'implĂ©menter un service Web sans authentification.

Moins

  • ORDS n'est pas inclus dans le package Oracle standard - il doit ĂȘtre installĂ© sĂ©parĂ©ment pour chaque serveur (des licences supplĂ©mentaires, comme dĂ©jĂ  mentionnĂ©, ne sont pas nĂ©cessaires). Cela peut ĂȘtre un problĂšme si vous avez des milliers de serveurs de base de donnĂ©es.

Personnalisation


ORDS peut ĂȘtre lancĂ© en deux modes: via le serveur d'applications ou en mode autonome.

Cet article traite uniquement de l'option à exécuter en mode autonome.

Pour que ORDS fonctionne, vous avez besoin de:

  1. Configurez les paramĂštres avant l'installation.
  2. Terminez l'installation d'ODRS.
  3. Lancez ORDS.
  4. Configurez ACL (pour le schéma de base de données souhaité).

RĂ©glages


La distribution ORDS a un fichier avec des paramÚtres qui ressemble à ceci par défaut:

db.hostname=
db.port=
db.servicename=
db.sid=
db.username=APEX_PUBLIC_USER
migrate.apex.rest=false
rest.services.apex.add=
rest.services.ords.add=true
schema.tablespace.default=SYSAUX
schema.tablespace.temp=TEMP
standalone.http.port=8080
standalone.static.images=
user.tablespace.default=USERS
user.tablespace.temp=TEMP

Une description des paramĂštres peut ĂȘtre trouvĂ©e dans la documentation

ParamĂštres pour le mode autonome:
ParamĂštreLa description
db.hostnameNom ou adresse IP du serveur de base de données Oracle
db.portPort DB (par exemple 1521)
db.servicenameBase de données de nom de service
db.usernameNom d'utilisateur de la passerelle PL / SQL. Par défaut = APEX_PUBLIC_USER, mais l'exemple ne prévoit pas d'utiliser APEX, vous pouvez donc laisser ce paramÚtre vide
db.passwordMot de passe utilisateur (Ă©galement Ă  ne pas remplir)
migrate.apex.restTransition des services APEX RESTful vers ORDS. Défini sur false si APEX n'est pas utilisé.
rest.services.apex.addConfigurer ORDS pour une utilisation dans APEX
rest.services.ords.addDĂ©finissez le schĂ©ma de base de donnĂ©es pour ORDS (ORDS_PUBLIC_USER et ORDS_METADATA). La valeur doit ĂȘtre vraie
schema.tablespace.defaultEspace table par défaut pour le schéma ORDS_METADATA
schema.tablespace.tempEspace disque logique temporaire pour le schéma ORDS_METADATA
standalone.http.portPort sur lequel ORDS s'exécutera. Ce port sera utilisé dans l'URI pour accéder à WS.
user.tablespace.defaultEspace table par défaut pour le schéma ORDS_PUBLIC_USER
user.tablespace.tempEspace table temporaire pour le schéma ORDS_PUBLIC_USER
Par conséquent, le contenu du fichier devrait ressembler à ceci:

db.hostname=your_server_host_name
db.port=1521
db.servicename=your_db_servicename
migrate.apex.rest=false
rest.services.apex.add=false
rest.services.ords.add=true
schema.tablespace.default=SYSAUX
schema.tablespace.temp=TEMP
standalone.http.port=8888
standalone.static.images=
user.tablespace.default=USERS
user.tablespace.temp=TEMP

Les réglages nécessaires sont terminés, vous pouvez procéder à l'installation.

Installation


Nous exécutons la commande dans l'OS:

java -jar ords.war

Par défaut, le fichier de configuration est extrait du répertoire paramssitué à cÎté de ords.war. Vous pouvez spécifier explicitement le chemin d'accÚs à ce fichier à l'aide du paramÚtre --parameterFile:

java -jar ords.war --parameterFile /path/to/params/myown_params.properties

Dans la boßte de dialogue d'installation, procédez comme suit:

  1. Nous indiquons le chemin d'accĂšs au rĂ©pertoire pour enregistrer la configuration (dans l'exemple, il est indiquĂ© conf - en consĂ©quence, dans le mĂȘme rĂ©pertoire oĂč se trouve le fichier ords.war, un rĂ©pertoire sera crĂ©Ă© confdans lequel les fichiers avec la configuration ORDS seront crĂ©Ă©s).
  2. AprÚs que la commande Entrez le mot de passe de la base de données pour ORDS_PUBLIC_USER s'affiche, nous entrons le mot de passe pour le schéma ORDS_PUBLIC_USER. Sous cet utilisateur, ORDS se connectera à la base de données.
  3. AprÚs que l'invite Entrez 1 si vous souhaitez utiliser PL / SQL Gateway ou 2 pour ignorer cette étape s'affiche, nous répondons «2», car nous n'allons pas utiliser APEX et nous n'avons pas besoin de migrer depuis mod_plsql.
  4. AprÚs que l'instruction Enter 1 si vous souhaitez démarrer en mode autonome ou 2 pour quitter [1] apparaisse, nous répondons «1».
  5. AprÚs que l'instruction Enter 1 if using HTTP or 2 if using HTTPS [1] s'affiche, nous répondons 1.

BoĂźte de dialogue d'installation
D:\ords-19.2.0.199.1647>java -jar ords.war install
This Oracle REST Data Services instance has not yet been configured.
Please complete the following prompts


Enter the location to store configuration data: conf
Enter the database password for ORDS_PUBLIC_USER:
Confirm password:
03, 2019 2:47:49 PM oracle.dbtools.rt.config.setup.SchemaSetup getInstallOrUpgrade
WARNING: Failed to connect to user ORDS_PUBLIC_USER jdbc:oracle:thin:@//***YOUR_HOST_NAME.DOMAIN***:1521/***YOUR_SERVICE_NAME.DOMAIN***

Enter 1 if you want to use PL/SQL Gateway or 2 to skip this step.
If using Oracle Application Express or migrating from mod_plsql then you must enter 1 [1]:2
03, 2019 2:48:32 PM
INFO: reloaded pools: []
Enter 1 if you wish to start in standalone mode or 2 to exit [1]:
Enter 1 if using HTTP or 2 if using HTTPS [1]:
2019-09-03 14:48:49.754:INFO::main: Logging initialized @4276887ms to org.eclipse.jetty.util.log.StdErrLog
03, 2019 2:48:49 PM
INFO: HTTP and HTTP/2 cleartext listening on port: 8082
03, 2019 2:48:50 PM
INFO: Disabling document root because the specified folder does not exist: D:\ords-19.2.0.199.1647\conf\ords\standalone\doc_root
Exception in thread "main" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at oracle.dbtools.jarcl.Entrypoint.invoke(Entrypoint.java:66)
at oracle.dbtools.jarcl.Entrypoint.main(Entrypoint.java:89)
Caused by: java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Unknown Source)
at java.lang.AbstractStringBuilder.ensureCapacityInternal(Unknown Source)
at java.lang.AbstractStringBuilder.append(Unknown Source)
at java.lang.StringBuilder.append(Unknown Source)
at java.lang.StringBuilder.append(Unknown Source)
at java.util.AbstractMap.toString(Unknown Source)
at java.lang.String.valueOf(Unknown Source)
at java.lang.StringBuilder.append(Unknown Source)
at oracle.dbtools.jarcl.zip.ZipIndex.toString(ZipIndex.java:166)
at java.lang.String.valueOf(Unknown Source)
at java.lang.StringBuilder.append(Unknown Source)
at oracle.dbtools.jarcl.JarClassLoader.toString(JarClassLoader.java:51)
at org.eclipse.jetty.server.ClassLoaderDump.dump(ClassLoaderDump.java:67)
at org.eclipse.jetty.util.component.Dumpable.dumpObjects(Dumpable.java:225)
at org.eclipse.jetty.util.component.ContainerLifeCycle.dumpObjects(ContainerLifeCycle.java:746)
at org.eclipse.jetty.server.handler.ContextHandler.dump(ContextHandler.java:259)
at org.eclipse.jetty.util.component.Dumpable.dumpObjects(Dumpable.java:162)
at org.eclipse.jetty.util.component.ContainerLifeCycle.dumpObjects(ContainerLifeCycle.java:746)
at org.eclipse.jetty.util.component.ContainerLifeCycle.dump(ContainerLifeCycle.java:701)
at org.eclipse.jetty.util.component.Dumpable.dump(Dumpable.java:62)
at org.eclipse.jetty.util.component.ContainerLifeCycle.dump(ContainerLifeCycle.java:684)
at oracle.dbtools.standalone.StandaloneConfiguration.start(StandaloneConfiguration.java:241)
at oracle.dbtools.standalone.Standalone.execute(Standalone.java:508)
at oracle.dbtools.cmdline.DefaultCommand.execute(DefaultCommand.java:137)
at oracle.dbtools.cmdline.Commands.execute(Commands.java:207)
at oracle.dbtools.cmdline.Commands.main(Commands.java:163)
at oracle.dbtools.cmdline.Commands.main(Commands.java:368)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at oracle.dbtools.jarcl.Entrypoint.invoke(Entrypoint.java:66)

En conséquence, un répertoire avec la configuration ORDS sera créé et les schémas d'utilitaires pour ORDS apparaßtront dans la base de données.

Voir Ă©galement: Installez Oracle REST Data Services 3.0.X en moins de 5 minutes .

lancement


Le démarrage en mode autonome s'effectue par la commande:

java -jar ords.war standalone

BoĂźte de dialogue de lancement
D:\ords-19.2.0.199.1647>java -jar ords.war standalone
2019-09-03 15:52:45.825:INFO::main: Logging initialized @2079ms to org.eclipse.jetty.util.log.StdErrLog
03, 2019 3:52:45 PM
INFO: HTTP and HTTP/2 cleartext listening on port: 8082
03, 2019 3:52:45 PM
INFO: Disabling document root because the specified folder does not exist: D:\ords-19.2.0.199.1647\conf\ords\standalone\doc_root
2019-09-03 15:52:47.124:INFO:oejs.Server:main: jetty-9.4.z-SNAPSHOT; built: 2019-05-02T09:46:34.874Z; git: 14f32d50076f2b706f41a33066eb364d8492e199; jvm 1.8.0_221-b11
2019-09-03 15:52:47.179:INFO:oejs.session:main: DefaultSessionIdManager workerName=node0
2019-09-03 15:52:47.179:INFO:oejs.session:main: No SessionScavenger set, using defaults
2019-09-03 15:52:47.180:INFO:oejs.session:main: node0 Scavenging every 660000ms
03, 2019 3:52:48 PM
INFO: Configuration properties for: |apex|pu|
db.hostname=***YOUR_HOST_NAME.DOMAIN***
db.password=******
db.port=1521
db.servicename=***YOUR_SERVICE_NAME.DOMAIN***
db.username=ORDS_PUBLIC_USER
resource.templates.enabled=true

03, 2019 3:52:48 PM
WARNING: *** jdbc.MaxLimit in configuration |apex|pu| is using a value of 10, this setting may not be sized adequately for a production environment ***
03, 2019 3:52:48 PM
WARNING: *** jdbc.InitialLimit in configuration |apex|pu| is using a value of 3, this setting may not be sized adequately for a production environment ***
03, 2019 3:52:50 PM
INFO: Oracle REST Data Services initialized
Oracle REST Data Services version : 19.2.0.r1991647
Oracle REST Data Services server info: jetty/9.4.z-SNAPSHOT

2019-09-03 15:52:50.484:INFO:oejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler@d56d67{/ords,null,AVAILABLE}
2019-09-03 15:52:50.658:INFO:oejs.AbstractConnector:main: Started ServerConnector@12325ad{HTTP/1.1,[http/1.1, h2c]}{0.0.
0.0:8082}
2019-09-03 15:52:50.659:INFO:oejs.Server:main: Started @6914ms

AprĂšs cela, ORDS est opĂ©rationnel. L'adresse du service Web sera http: // <nom d'hĂŽte>: / ords / ..., oĂč <nom d'hĂŽte> est le nom de l'ordinateur exĂ©cutant ORDS (il ne doit pas nĂ©cessairement correspondre au nom du serveur de base de donnĂ©es, c'est-Ă -dire que ORDS peut ĂȘtre exĂ©cutĂ© sur un autre hĂŽte ), <port> - le port spĂ©cifiĂ© dans la configuration ORDS.

Si vous le souhaitez, vous pouvez créer un script pour exécuter automatiquement ORDS au démarrage du systÚme d'exploitation.

ParamĂštre d'accĂšs


Et la derniĂšre Ă©tape consiste Ă  configurer l'ACL. Les Ă©tapes sont les mĂȘmes que pour l'utilisation d'Oracle WS natif.

Vous devez effectuer cette étape aprÚs la création du schéma de base de données, de sorte que les exemples ci-dessous indiquent séparément quand vous devez effectuer cette configuration. Jusqu'à présent, nous pouvons supposer que toutes les étapes préliminaires ont été achevées et poursuivre avec les exemples.

Exemple 1: gestionnaire d'une demande POST


Par exemple, considérons l'option d'implémentation d'interaction de style RPC, c'est-à-dire que nous allons créer une méthode de service Web, dont le gestionnaire sera une procédure par lots.

En effet, c'est dans cette version que le travail avec ORDS a été implémenté dans notre projet de réseau de distribution, et le résultat a répondu à ses attentes. Il s'est avéré un moyen rapide et universel de créer de nouvelles méthodes de services Web pour différents processus métier - du travail avec l'équipement à l'API pour les sites.

Comme mentionné ci-dessus, le support ORDS est également inclus dans SQL Developer (l'EDI de base de données développé par Oracle). Dans SQL Developer, la création de services Web est disponible directement à partir des éléments de menu ou du menu contextuel.

Dans cet article, des exemples sont réalisés à l'aide de SQL Developer (version 18), mais le code PL / SQL qui est exécuté dans la base de données à la suite d'actions dans l'IDE est également inclus.

La version de la base de données sur laquelle les expériences ont été effectuées:

SQL> SELECT v.BANNER FROM v$version v;
 
BANNER
--------------------------------------------------------------------------------
Oracle DATABASE 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
PL/SQL Release 12.2.0.1.0 - Production
CORE	12.2.0.1.0	Production
TNS FOR Linux: Version 12.2.0.1.0 - Production
NLSRTL Version 12.2.0.1.0 - Production

Création d'un utilisateur de test pour WS


Par exemple, nous avons à nouveau besoin d'un nouveau schéma - créez-le:

CREATE USER WS_TEST IDENTIFIED BY ws_test QUOTA 200M ON USERS;
GRANT CREATE SESSION, RESOURCE TO ws_test;

Configuration d'un schéma de base de données


Une fois le diagramme créé, il est nécessaire de le rendre accessible via ORDS.

Pour ça:

  1. Dans SQL Developer, créez une connexion pour WS_TEST.
  2. Dans la liste des connexions, appelez le menu contextuel de la nouvelle connexion. Choisissez Services REST → Activer les services REST ... :


  3. Dans la boĂźte de dialogue, cochez la case Ă  cĂŽtĂ© de Activer le schĂ©ma (ici, vous pouvez Ă©galement modifier le paramĂštre " Alias ​​de schĂ©ma " si vous souhaitez que le ws_testtexte soit affichĂ© dans l'URI au lieu du nom du schĂ©ma ):


  4. En cliquant sur «Suivant» , nous verrons le code PL / SQL qui sera Ă©ventuellement exĂ©cutĂ© dans la base de donnĂ©es (et que vous pourrez Ă©crire vous-mĂȘme sans utiliser l'IDE):



Référencement:

BEGIN
    ORDS.ENABLE_SCHEMA( p_enabled             => TRUE
                      , p_schema              => 'WS_TEST'
                      , p_url_mapping_type    => 'BASE_PATH'
                      , p_url_mapping_pattern => 'ws_test'
                      , p_auto_rest_auth      => FALSE);
 
    COMMIT;
END;
/

Création d'un module et d'un modÚle


Ensuite, vous devez créer un module et un modÚle pour la ressource.

Un module est une unité structurelle qui vous permet de regrouper plusieurs modÚles de ressources logiquement liés.

Un modÚle est un service Web spécifique servant un ensemble spécifique de méthodes pour une ressource.

À la source :

module de ressources: unité organisationnelle utilisée pour regrouper les modÚles de ressources associés.

ModÚle de ressource: service RESTful individuel capable de traiter les demandes d'un certain ensemble d'URI (Universal Resource Identifiers). L'ensemble d'URI est défini par le modÚle d'URI du modÚle de ressource.


Par exemple, pour une boutique en ligne, un module peut ĂȘtre appelĂ©shop - dans ce module, toutes les API du magasin seront combinĂ©es. Les modĂšles peuvent ĂȘtre des ressources spĂ©cifiques, par exemple, une commande (modĂšle order), un catalogue de produits (modĂšle item), un paiement (modĂšle payment), etc.

Pour créer un module et un modÚle, vous devez effectuer les étapes suivantes:

  1. Dans l'arborescence d'objets, ouvrez la section REST Data Services, appelez le menu contextuel dans la section Modules , sélectionnez Nouveau module ... :


  2. Dans la boßte de dialogue de création de module, spécifiez le nom du module ( shop), le préfixe URI (nous spécifions également shop - dans l'exemple ci-dessous, nous voyons immédiatement ce que sera le modÚle d'adresse de service Web), mettez un daw devant Publier , cliquez sur "Suivant>" :


  3. Dans la boßte de dialogue suivante, spécifiez le nom du modÚle, par exemple order, et cliquez à nouveau sur "Suivant>" .

    Dans la derniÚre boßte de dialogue, nous voyons tous les paramÚtres saisis du module et du modÚle. Sous l'onglet SQL , vous pouvez voir le code PL / SQL qui sera exécuté dans la base de données lorsque vous cliquez sur Terminer :



Pour créer un module shop , vous pouvez ajouter plusieurs motifs - également dans l'arborescence d'objets, le menu contextuel et en sélectionnant le modÚle ... Ajouter le .

Liste de code pour créer un module et un modÚle
BEGIN
    ORDS.DEFINE_MODULE( p_module_name    => 'shop'
                      , p_base_path      => 'shop'
                      , p_items_per_page =>  25
                      , p_status         => 'PUBLISHED'
                      , p_comments       => NULL);
 
    ORDS.DEFINE_TEMPLATE( p_module_name    => 'shop'
                        , p_pattern        => 'order'
                        , p_priority       => 0
                        , p_etag_type      => 'HASH'
                        , p_etag_query     => NULL
                        , p_comments       => NULL);
 
    COMMIT;
END;
/

CrĂ©ation d'un gestionnaire de requĂȘtes HTTP


Nous devons maintenant crĂ©er un gestionnaire de requĂȘtes HTTP pour notre service.

Tout d'abord, nous devons créer des objets de base de données qui contiendront la logique de traitement des demandes.

Nous avons besoin d'une table de journalisation et d'un package dans lequel il y aura un code de gestionnaire.

Créez une table à l'aide d'un script:
CREATE TABLE T_WS_LOG
(
  id_log          NUMBER GENERATED ALWAYS AS IDENTITY,
  message         VARCHAR2(2000),
  request_header  VARCHAR2(2000),
  request_body    CLOB,
  response_header VARCHAR2(2000),
  response_body   CLOB,
  dtz_log         TIMESTAMP(6) WITH TIME ZONE DEFAULT SYSTIMESTAMP
);
COMMENT ON TABLE T_WS_LOG IS '  HTTP- (ORDS)';
COMMENT ON COLUMN T_WS_LOG.id_log IS '';
COMMENT ON COLUMN T_WS_LOG.message IS ' ';
COMMENT ON COLUMN T_WS_LOG.request_header IS ' ';
COMMENT ON COLUMN T_WS_LOG.request_body IS ' ';
COMMENT ON COLUMN T_WS_LOG.response_header IS ' ';
COMMENT ON COLUMN T_WS_LOG.response_body IS ' ';
COMMENT ON COLUMN T_WS_LOG.dtz_log IS '/  ';
ALTER TABLE T_WS_LOG ADD CONSTRAINT PK_T_WS_LOG PRIMARY KEY (ID_LOG) USING INDEX;

Créez un package:
CREATE OR REPLACE PACKAGE PK_ORDS_API IS
 
 
FUNCTION blob2clob
    ( a_blob            BLOB
    , a_from_charset    VARCHAR2  := 'AMERICAN_AMERICA.AL32UTF8'
    , a_to_charset      VARCHAR2  := 'AMERICAN_AMERICA.AL32UTF8'
    ) RETURN            CLOB;
 
 
PROCEDURE process_request
    ( a_request     CLOB
    );
 
 
END PK_ORDS_API;
/
 
CREATE OR REPLACE PACKAGE BODY PK_ORDS_API IS
 
 
FUNCTION blob2clob
    ( a_blob            BLOB
    , a_from_charset    VARCHAR2  := 'AMERICAN_AMERICA.AL32UTF8'
    , a_to_charset      VARCHAR2  := 'AMERICAN_AMERICA.AL32UTF8'
    ) RETURN            CLOB
AS
    l_clob      CLOB;
    l_amount    NUMBER := 2000;
    l_offset    NUMBER := 1;
    l_buffer    VARCHAR2(32767);
    l_length    PLS_INTEGER := dbms_lob.getlength(a_blob);
BEGIN
    dbms_lob.createtemporary(l_clob, TRUE);
    dbms_lob.OPEN(l_clob, dbms_lob.lob_readwrite);
    WHILE l_offset <= l_length LOOP
        l_buffer := UTL_RAW.cast_to_varchar2(UTL_RAW.convert( r            => dbms_lob.substr(a_blob, l_amount, l_offset)
                                                            , from_charset => a_from_charset
                                                            , to_charset   => a_to_charset));
        IF LENGTH(l_buffer) > 0 THEN
            dbms_lob.writeappend(l_clob, LENGTH(l_buffer), l_buffer);
        END IF;
        l_offset := l_offset + l_amount;
        EXIT WHEN l_offset > l_length;
    END LOOP;
    RETURN l_clob;
END blob2clob;
 
 
PROCEDURE process_request
    ( a_request     CLOB
    )
AS
    TYPE TStringHash IS TABLE OF VARCHAR2(256) INDEX BY VARCHAR2(256);
    lh_hdr              TStringHash;
    l_hdr               VARCHAR2(256);
    l_resp              CLOB;
    l_response_status   INTEGER := 200;
    l_ccontent_type     VARCHAR2(64) := 'application/json';
    l_in_headers        VARCHAR2(32767);
BEGIN
    --      
    lh_hdr('SERVER_SOFTWARE')       := OWA_UTIL.get_cgi_env('SERVER_SOFTWARE');
    lh_hdr('SERVER_NAME')           := OWA_UTIL.get_cgi_env('SERVER_NAME');
    lh_hdr('GATEWAY_INTERFACE')     := OWA_UTIL.get_cgi_env('GATEWAY_INTERFACE');
    lh_hdr('SERVER_PROTOCOL')       := OWA_UTIL.get_cgi_env('SERVER_PROTOCOL');
    lh_hdr('SERVER_PORT')           := OWA_UTIL.get_cgi_env('SERVER_PORT');
    lh_hdr('REQUEST_METHOD')        := OWA_UTIL.get_cgi_env('REQUEST_METHOD');
    lh_hdr('PATH_INFO')             := OWA_UTIL.get_cgi_env('PATH_INFO');
    lh_hdr('PATH_TRANSLATED')       := OWA_UTIL.get_cgi_env('PATH_TRANSLATED');
    lh_hdr('SCRIPT_NAME')           := OWA_UTIL.get_cgi_env('SCRIPT_NAME');
    lh_hdr('QUERY_STRING')          := OWA_UTIL.get_cgi_env('QUERY_STRING');
    lh_hdr('REMOTE_HOST')           := OWA_UTIL.get_cgi_env('REMOTE_HOST');
    lh_hdr('REMOTE_ADDR')           := OWA_UTIL.get_cgi_env('REMOTE_ADDR');
    lh_hdr('AUTH_TYPE')             := OWA_UTIL.get_cgi_env('AUTH_TYPE');
    lh_hdr('REMOTE_USER')           := OWA_UTIL.get_cgi_env('REMOTE_USER');
    lh_hdr('REMOTE_IDENT')          := OWA_UTIL.get_cgi_env('REMOTE_IDENT');
    lh_hdr('CONTENT-TYPE')          := OWA_UTIL.get_cgi_env('CONTENT-TYPE');
    lh_hdr('CONTENT-LENGTH')        := OWA_UTIL.get_cgi_env('CONTENT-LENGTH');
    lh_hdr('HTTP_ACCEPT')           := OWA_UTIL.get_cgi_env('HTTP_ACCEPT');
    lh_hdr('HTTP_ACCEPT_LANGUAGE')  := OWA_UTIL.get_cgi_env('HTTP_ACCEPT_LANGUAGE');
    lh_hdr('HTTP_USER_AGENT')       := OWA_UTIL.get_cgi_env('HTTP_USER_AGENT');
    lh_hdr('HTTP_COOKIE')           := OWA_UTIL.get_cgi_env('HTTP_COOKIE');
 
    l_hdr := lh_hdr.FIRST;
    WHILE l_hdr IS NOT NULL LOOP
        IF lh_hdr(l_hdr) IS NOT NULL THEN
            l_in_headers := l_in_headers||CHR(10)||l_hdr||': '||lh_hdr(l_hdr);
        END IF;
        l_hdr := lh_hdr.NEXT(l_hdr);
    END LOOP;
 
    l_resp := '{ "result" : "success" }';
 
    INSERT INTO t_ws_log
        ( message
        , request_header
        , request_body
        , response_header
        , response_body)
    VALUES
        ( NULL
        , l_in_headers
        , a_request
        , 'Content-Type: '||l_ccontent_type
        , l_resp
        );
 
    OWA_UTIL.STATUS_LINE(nstatus => l_response_status, bclose_header => FALSE);
    OWA_UTIL.MIME_HEADER(ccontent_type => l_ccontent_type, bclose_header => FALSE);
    OWA_UTIL.HTTP_HEADER_CLOSE();
    htp.p(l_resp);
END process_request;
 
END PK_ORDS_API;
/

Maintenant, pour le modÚle créé, vous devez ajouter un gestionnaire. Ajoutez un gestionnaire pour la méthode HTTP POST.

Pour ce faire, procédez comme suit:

  1. Nous appelons le menu contextuel du modÚle, sélectionnez Ajouter un gestionnaire , puis sélectionnez la méthode HTTP:

  2. . SQL Worksheet PL/SQL-, HTTP- POST. , process_request . , bind- :body — ORDS, ( BLOB). . :body_text, CLOB. , , , ORDS . :body_text , «» . :body, CLOB . , :


  3. Save REST Handler — .

    POST-:

    DECLARE
        l_blob BLOB := :body;
    BEGIN
        PK_ORDS_API.process_request(a_request => PK_ORDS_API.blob2clob(l_blob));
    EXCEPTION
        WHEN OTHERS THEN
            OWA_UTIL.STATUS_LINE(nstatus => 500, bclose_header => FALSE);
            OWA_UTIL.MIME_HEADER(ccontent_type => 'application/json');
            htp.p('{ "result" : "error", "message" : "'||SQLERRM||'" }');
    END;

    Si nĂ©cessaire, vous pouvez obtenir le code PL / SQL pour crĂ©er un gestionnaire. Pour ce faire, dans le menu contextuel du module ORDS, sĂ©lectionnez DĂ©finition REST puis spĂ©cifiez oĂč sortir le script de crĂ©ation de module, par exemple, dans le presse-papiers:


Le code résultant pour créer le module
-- Generated by Oracle SQL Developer REST Data Services 18.1.0.095.1630
-- Exported REST Definitions from ORDS Schema Version 18.4.0.r3541002
-- Schema: WS_TEST   Date: Wed Oct 23 20:19:54 MSK 2019
--
BEGIN
  ORDS.ENABLE_SCHEMA(
      p_enabled             => TRUE,
      p_schema              => 'WS_TEST',
      p_url_mapping_type    => 'BASE_PATH',
      p_url_mapping_pattern => 'ws_test',
      p_auto_rest_auth      => TRUE);    
 
  ORDS.DEFINE_MODULE(
      p_module_name    => 'shop',
      p_base_path      => '/shop/',
      p_items_per_page =>  25,
      p_status         => 'PUBLISHED',
      p_comments       => NULL);      
  ORDS.DEFINE_TEMPLATE(
      p_module_name    => 'shop',
      p_pattern        => 'order',
      p_priority       => 0,
      p_etag_type      => 'HASH',
      p_etag_query     => NULL,
      p_comments       => NULL);
  ORDS.DEFINE_HANDLER(
      p_module_name    => 'shop',
      p_pattern        => 'order',
      p_method         => 'POST',
      p_source_type    => 'plsql/block',
      p_items_per_page =>  0,
      p_mimes_allowed  => '',
      p_comments       => NULL,
      p_source         => 
'DECLARE
    l_blob BLOB := :body;
BEGIN
    PK_ORDS_API.process_request(a_request => PK_ORDS_API.blob2clob(l_blob));
EXCEPTION
    WHEN OTHERS THEN
        OWA_UTIL.STATUS_LINE(nstatus => 500, bclose_header => FALSE);
        OWA_UTIL.MIME_HEADER(ccontent_type => ''application/json'');
        htp.p(''{ "result" : "error", "message" : "''||SQLERRM||''" }'');
END;'
      );
 
 
  COMMIT; 
END;


Remarque: si vous exécutez à ORDS.DEFINE_MODULEnouveau la procédure de création de module , tous les modÚles de ce module seront automatiquement supprimés et il n'y aura aucun avertissement à ce sujet!

Exemple d'appel


C'est lĂ  que notre service Web est prĂȘt. Reste Ă  vĂ©rifier son travail.

Pour vérifier, nous exécutons la demande:

POST http://****:8888/ords/ws_test/shop/order HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: application/json
Content-Length: 22
Host: ****:8888
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
 
{ "message" : "test" }

En réponse, nous obtenons:

HTTP/1.1 200 OK
Date: Wed, 23 Oct 2019 16:54:53 GMT
Content-Type: application/json
Transfer-Encoding: chunked
 
{ "result" : "success" }

Le résultat de l'exécution de la méthode est une entrée avec le corps de la demande et la réponse dans la table du journal:



Comme vous pouvez le voir, la demande HTTP envoyée a été traitée avec succÚs par la procédure à partir du paquet.

ParamĂštres de la demande


Ci-dessus, nous avons déjà vu le résultat d'un simple service web. Maintenant, compliquons un peu la tùche en ajoutant des paramÚtres supplémentaires à la demande.

Il existe deux façons de transmettre des paramÚtres:

Via l'URL. Les paramÚtres sont définis dans l'URL sous la forme standard:

http://...URI...?p1=val1&p2=val2

Via HEADER. Les paramĂštres sont dĂ©finis dans l'en-tĂȘte de la demande comme p1: val1

Dans ORDS dans le gestionnaire de demandes, les paramÚtres sont définis comme des variables de liaison.

Nous ajoutons deux paramĂštres Ă  l'exemple prĂ©cĂ©dent: prm1- paramĂštre dans l'URI, prm2- paramĂštre dans l'en-tĂȘte de la requĂȘte.

Pour traiter ces paramĂštres, PK_ORDS_API.process_request:nous ajoutons la procĂ©dure, ajoutons les paramĂštres a_prm_uriet a_prm_hdr, Ă  laquelle viendront les valeurs de nos paramĂštres de la requĂȘte.

ProcĂ©dure de gestion des requĂȘtes avec de nouveaux paramĂštres
PROCEDURE process_request
    ( a_request     CLOB
    , a_prm_uri     VARCHAR2 := NULL
    , a_prm_hdr     VARCHAR2 := NULL
    )
AS
    TYPE TStringHash IS TABLE OF VARCHAR2(256) INDEX BY VARCHAR2(256);
    lh_hdr              TStringHash;
    l_hdr               VARCHAR2(256);
    l_resp              CLOB;
    l_response_status   INTEGER := 200;
    l_ccontent_type     VARCHAR2(64) := 'application/json';
    l_in_headers        VARCHAR2(32767);
BEGIN
    --      
    lh_hdr('SERVER_SOFTWARE')       := OWA_UTIL.get_cgi_env('SERVER_SOFTWARE');
    lh_hdr('SERVER_NAME')           := OWA_UTIL.get_cgi_env('SERVER_NAME');
    lh_hdr('GATEWAY_INTERFACE')     := OWA_UTIL.get_cgi_env('GATEWAY_INTERFACE');
    lh_hdr('SERVER_PROTOCOL')       := OWA_UTIL.get_cgi_env('SERVER_PROTOCOL');
    lh_hdr('SERVER_PORT')           := OWA_UTIL.get_cgi_env('SERVER_PORT');
    lh_hdr('REQUEST_METHOD')        := OWA_UTIL.get_cgi_env('REQUEST_METHOD');
    lh_hdr('PATH_INFO')             := OWA_UTIL.get_cgi_env('PATH_INFO');
    lh_hdr('PATH_TRANSLATED')       := OWA_UTIL.get_cgi_env('PATH_TRANSLATED');
    lh_hdr('SCRIPT_NAME')           := OWA_UTIL.get_cgi_env('SCRIPT_NAME');
    lh_hdr('QUERY_STRING')          := OWA_UTIL.get_cgi_env('QUERY_STRING');
    lh_hdr('REMOTE_HOST')           := OWA_UTIL.get_cgi_env('REMOTE_HOST');
    lh_hdr('REMOTE_ADDR')           := OWA_UTIL.get_cgi_env('REMOTE_ADDR');
    lh_hdr('AUTH_TYPE')             := OWA_UTIL.get_cgi_env('AUTH_TYPE');
    lh_hdr('REMOTE_USER')           := OWA_UTIL.get_cgi_env('REMOTE_USER');
    lh_hdr('REMOTE_IDENT')          := OWA_UTIL.get_cgi_env('REMOTE_IDENT');
    lh_hdr('CONTENT-TYPE')          := OWA_UTIL.get_cgi_env('CONTENT-TYPE');
    lh_hdr('CONTENT-LENGTH')        := OWA_UTIL.get_cgi_env('CONTENT-LENGTH');
    lh_hdr('HTTP_ACCEPT')           := OWA_UTIL.get_cgi_env('HTTP_ACCEPT');
    lh_hdr('HTTP_ACCEPT_LANGUAGE')  := OWA_UTIL.get_cgi_env('HTTP_ACCEPT_LANGUAGE');
    lh_hdr('HTTP_USER_AGENT')       := OWA_UTIL.get_cgi_env('HTTP_USER_AGENT');
    lh_hdr('HTTP_COOKIE')           := OWA_UTIL.get_cgi_env('HTTP_COOKIE');
    lh_hdr('a_prm_uri')             := a_prm_uri;
    lh_hdr('a_prm_hdr')             := a_prm_hdr;
 
    l_hdr := lh_hdr.FIRST;
    WHILE l_hdr IS NOT NULL LOOP
        IF lh_hdr(l_hdr) IS NOT NULL THEN
            l_in_headers := l_in_headers||CHR(10)||l_hdr||': '||lh_hdr(l_hdr);
        END IF;
        l_hdr := lh_hdr.NEXT(l_hdr);
    END LOOP;
 
    l_resp := '{ "result" : "success" }';
 
    INSERT INTO t_ws_log
        ( message
        , request_header
        , request_body
        , response_header
        , response_body)
    VALUES
        ( NULL
        , l_in_headers
        , a_request
        , 'Content-Type: '||l_ccontent_type
        , l_resp);
 
    OWA_UTIL.STATUS_LINE(nstatus => l_response_status, bclose_header => FALSE);
    OWA_UTIL.MIME_HEADER(ccontent_type => l_ccontent_type, bclose_header => FALSE);
    OWA_UTIL.HTTP_HEADER_CLOSE();
    htp.p(l_resp);
END process_request;

Dans la procédure, nous enregistrons simplement les valeurs des nouveaux paramÚtres dans le journal.

Ajoutez de nouveaux paramĂštres au gestionnaire de requĂȘtes POST - sous la forme de variables de liaison :prm_uriet :prm_hdr.

Gestionnaire de la demande de requĂȘte POST avec de nouveaux paramĂštres:

DECLARE
    l_blob BLOB := :body;
BEGIN
    PK_ORDS_API.process_request(a_request => PK_ORDS_API.blob2clob(l_blob), a_prm_uri => :prm_uri, a_prm_hdr => :prm_hdr);
EXCEPTION
    WHEN OTHERS THEN
        OWA_UTIL.STATUS_LINE(nstatus => 500, bclose_header => FALSE);
        OWA_UTIL.MIME_HEADER(ccontent_type => 'application/json');
        htp.p('{ "result" : "error", "message" : "'||SQLERRM||'" }');
END;

Dans le gestionnaire, sous l'onglet ParamÚtres , déclarez les variables: sous


cette forme, le premier champ ( nom ) contient le nom du paramÚtre attendu dans la demande, le deuxiÚme champ ( paramÚtre de liaison) - le nom de la variable de liaison qui sera spécifiée dans le gestionnaire de cette demande.

Exécutons la demande avec de nouveaux paramÚtres:



Résultat - les paramÚtres de la demande ont été enregistrés dans le journal:


Veuillez noter que les paramĂštres de l'URI peuvent Ă©galement ĂȘtre rĂ©cupĂ©rĂ©s Ă  partir de la variable CGI QUERY_STRING, c'est-Ă -dire que pour obtenir les paramĂštres, il n'est pas nĂ©cessaire de dĂ©marrer les variables de liaison - vous pouvez les analyser dans la procĂ©dure du gestionnaire demande.

Variables CGI


Lorsque vous travaillez avec HTTP dans Oracle, il est possible d'obtenir les valeurs des variables d'environnement qui reflÚtent le contexte de la demande HTTP. Vous pouvez obtenir les valeurs des variables en utilisant la procédure OWA_UTIL.get_cgi_env.

Liste des variables CGI disponibles en PL / SQL
APEX_LISTENER_VERSION
GATEWAY_INTERFACE
GATEWAY_IVERSION
HTTP_ACCEPT_ENCODING
HTTP_HOST
HTTP_PORT
HTTP_USER_AGENT
PATH_ALIAS
PATH_INFO
PLSQL_GATEWAY
QUERY_STRING
REMOTE_ADDR
REMOTE_USER
REQUEST_CHARSET
REQUEST_IANA_CHARSET
REQUEST_METHOD
REQUEST_PROTOCOL
REQUEST_SCHEME
SCRIPT_NAME
SERVER_NAME
SERVER_PORT
SERVER_PROTOCOL
SERVER_SOFTWARE
WEB_AUTHENT_PREFIX
host
user-agent
CONTENT-LENGTH
CONTENT-TYPE

Voir aussi: En- tĂȘtes HTTP (OWA_UTIL) et Variables de liaison spĂ©cifiques Ă  ORDS

Exemple 2: accĂšs Ă  une table via ORDS


Dans cet exemple, nous considérons l'organisation de l'accÚs à un objet de base de données (à une table) via ORDS.

Comme dans l'exemple précédent, nous rendons l'accÚs sans autorisation. Découvrez comment sécuriser l'accÚs aux ressources dans la documentation .

Pour rendre un objet de base de données accessible via ORDS, vous devez effectuer une seule étape - la commande ORDS.ENABLE_OBJECT. AprÚs cela, l'objet est accessible par un URI de la forme:

http://<HOST>:<PORT>/ords/<SchemaAlias>/<ObjectAlias>
.

Créer un motif de test


Pour un exemple nous allons créer le tableau "Commandes".

Script de création de table:

CREATE TABLE T_ORDER
(
  id_order   NUMBER NOT NULL,
  NUM        VARCHAR2(32),
  buyer_name VARCHAR2(256),
  dt_order   DATE,
  memo       VARCHAR2(2000)
);
 
COMMENT ON TABLE T_ORDER IS '';
COMMENT ON COLUMN T_ORDER.id_order IS ' ';
COMMENT ON COLUMN T_ORDER.num IS ' ';
COMMENT ON COLUMN T_ORDER.buyer_name IS ' ';
COMMENT ON COLUMN T_ORDER.dt_order IS '  ';
COMMENT ON COLUMN T_ORDER.memo IS '';
ALTER TABLE T_ORDER ADD CONSTRAINT PK_T_ORDER PRIMARY KEY (ID_ORDER) USING INDEX;

AccĂšs Ă  la table d'ouverture via ORDS


  1. Dans SQL Developer Invoke le menu contextuel de la table nécessaire, sélectionnez l'option Activer le service le reste ... .



  2. Dans la fenĂȘtre des paramĂštres d'accĂšs, cochez la case Activer l'objet , dĂ©cochez la case Autorisation requise , cliquez sur "Terminer" (ou "Suivant" pour voir le code PL / SQL reçu):



  3. AprÚs avoir effectué ces étapes, la table T_ORDERdevient disponible via HTTP, l'URI de base pour accéder à la ressource:

    http://<server>:<port>/ords/ws_test/t_order

    Liste d'inclusion de table:

    DECLARE
      PRAGMA AUTONOMOUS_TRANSACTION;
    BEGIN
     
        ORDS.ENABLE_OBJECT(p_enabled => TRUE,
                           p_schema => 'WS_TEST',
                           p_object => 'T_ORDER',
                           p_object_type => 'TABLE',
                           p_object_alias => 't_order',
                           p_auto_rest_auth => FALSE);
     
        commit;
     
    END;
    /


Créer ou modifier un enregistrement


L'accÚs à la table est ouvert - nous vérifions comment vous pouvez créer et modifier des enregistrements dans la table via ORDS.

Pour créer un enregistrement, nous exécutons la demande PUT.

Dans la documentation ORDS, la description suivante PUTest spécifiée dans la description de la méthode :

PUT http://<HOST>:<PORT>/ords/<SchemaAlias>/<ObjectAlias>/<KeyValues>

Autrement dit, le champ KeyValues(clĂ© d'enregistrement) doit ĂȘtre rempli mĂȘme pour un nouvel enregistrement en cours de crĂ©ation. La requĂȘte elle-mĂȘme doit rĂ©pertorier tous les champs de la table (mais le champ clĂ© peut ĂȘtre omis).

EnquĂȘte
PUT http://<server>:<port>/ords/ws_test/t_order/25 HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: application/json;charset=UTF-8
Content-Length: 157
Host: <server>:<port>
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
 
{
	"num" : "ords-3472634",
	"buyer_name" : "Buyer Name",
	"dt_order" : "2019-10-25T12:00:00Z",
	"memo" : "  1"
}

En rĂ©ponse, nous obtenons tous les champs de l'enregistrement qui vient d'ĂȘtre crĂ©Ă©:

HTTP/1.1 200 OK
Content-Type: application/json
Content-Location: http://<server>:<port>/ords/ws_test/t_order/25
ETag: "..."
Transfer-Encoding: chunked
 
{
   "id_order": 25,
   "num": "ords-3472634",
   "buyer_name": "Buyer Name",
   "dt_order": "2019-10-25T12:00:00Z",
   "memo": "  1",
   "links":    [
            {
         "rel": "self",
         "href": "http://<server>:<port>/ords/ws_test/t_order/25"
      },
            {
         "rel": "edit",
         "href": "http://<server>:<port>/ords/ws_test/t_order/25"
      },
            {
         "rel": "describedby",
         "href": "http://<server>:<port>/ords/ws_test/metadata-catalog/t_order/item"
      },
            {
         "rel": "collection",
         "href": "http://<server>:<port>/ords/ws_test/t_order/"
      }
   ]
}

Nous regardons le contenu du tableau - notre nouvel enregistrement est apparu:



Pour changer l'enregistrement, nous appelons la mĂȘme mĂ©thode PUT. Modifiez la note dans notre commande:

PUT http://<server>:<port>/ords/ws_test/t_order/25 HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: application/json;charset=UTF-8
Content-Length: 178
Host: <server>:<port>
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
 
{
	"num" : "ords-3472634",
	"buyer_name" : "Buyer Name",
	"dt_order" : "2019-10-25T12:00:00Z",
	"memo" : "  1.  "
}

Dans la rĂ©ponse, nous obtenons le mĂȘme JSON avec les paramĂštres de l'enregistrement modifiĂ©. Dans le tableau, nous voyons que la note a Ă©tĂ© mise Ă  jour:



Récupération des enregistrements d'une table


Il existe trois modes d'interrogation des données d'une table:

  1. Demande de page:

    GET http://<HOST>:<PORT>/ords/<SchemaAlias>/<ObjectAlias>/?offset=<Offset>&limit=<Limit>
  2. Demande de conditions:

     GET http://<HOST>:<PORT>/ords/<SchemaAlias>/<ObjectAlias>/?q=<FilterClause>
  3. Demande de clé primaire:

    GET http://<HOST>:<PORT>/ords/<SchemaAlias>/<ObjectAlias>/<KeyValues>

Pour obtenir tous les enregistrements, vous pouvez exĂ©cuter la requĂȘte sans spĂ©cifier de paramĂštres:

GET http://<server>:<port>/ords/ws_test/t_order/

RĂ©ponse
HTTP/1.1 200 OK
Date: Fri, 25 Oct 2019 15:39:58 GMT
Content-Type: application/json
ETag: "..."
Transfer-Encoding: chunked
 
{
   "items": [   {
      "id_order": 25,
      "num": "ords-3472634",
      "buyer_name": "Buyer Name",
      "dt_order": "2019-10-25T12:00:00Z",
      "memo": "ŃžÂ”Đƒâ€šŃ•Đ†â€č№ ·°є°· 1.  Â·Ń˜Â”Đ…â€šĐŠ Ń—Đ‚Ń˜Â”â€ĄÂ°Đ…Â”",
      "links": [      {
         "rel": "self",
         "href": "http://<server>:<port>/ords/ws_test/t_order/25"
      }]
   }],
   "hasMore": false,
   "limit": 25,
   "offset": 0,
   "count": 1,
   "links":    [
            {
         "rel": "self",
         "href": "http://<server>:<port>/ords/ws_test/t_order/"
      },
            {
         "rel": "edit",
         "href": "http://<server>:<port>/ords/ws_test/t_order/"
      },
            {
         "rel": "describedby",
         "href": "http://<server>:<port>/ords/ws_test/metadata-catalog/t_order/"
      },
            {
         "rel": "first",
         "href": "http://<server>:<port>/ords/ws_test/t_order/"
      }
   ]
}

Comment demander Ă  Oracle d'ajouter un encodage Ă  l'en-tĂȘte Content-Type est une question ouverte.

GET http://<server>:<port>/ords/ws_test/t_order/25

RĂ©ponse
HTTP/1.1 200 OK
Date: Fri, 25 Oct 2019 15:44:35 GMT
Content-Type: application/json
ETag: "..."
Transfer-Encoding: chunked
 
{
   "id_order": 25,
   "num": "ords-3472634",
   "buyer_name": "Buyer Name",
   "dt_order": "2019-10-25T12:00:00Z",
   "memo": "ŃžÂ”Đƒâ€šŃ•Đ†â€č№ ·°є°· 1.  Â·Ń˜Â”Đ…â€šĐŠ Ń—Đ‚Ń˜Â”â€ĄÂ°Đ…Â”",
   "links":    [
            {
         "rel": "self",
         "href": "http://<server>:<port>/ords/ws_test/t_order/25"
      },
            {
         "rel": "edit",
         "href": "http://<server>:<port>/ords/ws_test/t_order/25"
      },
            {
         "rel": "describedby",
         "href": "http://<server>:<port>/ords/ws_test/metadata-catalog/t_order/item"
      },
            {
         "rel": "collection",
         "href": "http://<server>:<port>/ords/ws_test/t_order/"
      }
   ]
}

Supprimer l'enregistrement


Pour supprimer, utilisez la méthode HTTP DELETE.

EnquĂȘte:

DELETE http://<server>:<port>/ords/ws_test/t_order/?q={"id_order":25}

La demande dans sa forme originale:

DELETE http://<server>:<port>/ords/ws_test/t_order/?q=%7B%22id_order%22%3A25%7D

RĂ©ponse:

HTTP/1.1 200 OK
Date=Fri, 25 Oct 2019 16:23:39 GMT
Content-Type=application/json
Transfer-Encoding=chunked
 
{"rowsDeleted":1}

résultats


ORDS est un mĂ©canisme assez flexible et polyvalent pour travailler avec des services Web, qui vous permet de mettre en Ɠuvre un REST Ă  part entiĂšre. En termes de performances, il est de loin supĂ©rieur Ă  Native Oracle WS avec sa lourde analyse XML interne. Pour implĂ©menter un systĂšme trĂšs chargĂ©, cette approche ne convient pas: dans ce cas, une pile technologique diffĂ©rente est nĂ©cessaire - un serveur d'applications distinct, des requĂȘtes de proxy, des bases de donnĂ©es en cluster, etc. Cependant, pour la mise en Ɠuvre de systĂšmes avec un nombre relativement faible de requĂȘtes HTTP (jusqu'Ă  10-20 par seconde), ORDS est l'approche optimale en termes de performances et de flexibilitĂ©. ORDS est infĂ©rieur Ă  Native Oracle WS uniquement en termes de gĂ©nĂ©ration d'une spĂ©cification de service Web: ce dernier fournit une spĂ©cification entiĂšrement finalisĂ©e (WSDL) qui peut ĂȘtre fournie «telle quelle» aux consommateurs du service. ORDS a Ă©galement la capacitĂ©gĂ©nĂ©rer une description, mais pour l'approche considĂ©rĂ©e dans cet article avec un service entiĂšrement universel (lorsqu'il existe une procĂ©dure de traitement commune pour tous les services), la gĂ©nĂ©ration automatique de la spĂ©cification devient impossible. Oracle ne gĂ©nĂ©rera qu'une spĂ©cification de niveau supĂ©rieur et les piĂšces (modĂšles de donnĂ©es) devront ĂȘtre dĂ©crites manuellement.

Approches alternatives


Servlet Java


Cette option de crĂ©ation de services Web dans la mĂ©thode de configuration est similaire Ă  Native Oracle WS: elle nĂ©cessite Ă©galement l'utilisation du serveur HTTP intĂ©grĂ© d'Oracle, ainsi que des paramĂštres ACL (comme d'ailleurs toutes les autres mĂ©thodes). Mais, contrairement Ă  Native Oracle WS, cette option fonctionne avec HTTP pur. Les gestionnaires des demandes dans ce cas sont Ă©crits en Java et ne regarder que le type HTTP demande ( PUT, GET, POST, et ainsi de suite, bien qu'il puisse ĂȘtre fait et un gestionnaire pour tous les types), et la logique de traitement reste entiĂšrement Ă  la discrĂ©tion du promoteur. Vous pouvez transfĂ©rer le corps de la demande «tel quel» dans la logique de la base de donnĂ©es, le dĂ©sassembler et le traiter lĂ -bas, vous pouvez laisser une partie de la logique du cĂŽtĂ© du gestionnaire Java et appeler la procĂ©dure souhaitĂ©e Ă  partir de la base de donnĂ©es en fonction des donnĂ©es fournies dans la demande.

Cette approche de la mise en Ɠuvre des services Web est assez universelle et ne nĂ©cessite pas non plus l'installation de composants supplĂ©mentaires. Nous n'avons pas rĂ©ussi Ă  l'appliquer uniquement en raison des exigences strictes du service: nous avions besoin d'un service Web qui ne nĂ©cessitait pas d'authentification. Lors de la mise en Ɠuvre de cette approche, l'authentification est requise et cette exigence n'a pas pu ĂȘtre contournĂ©e.

Voir la documentation Oracle pour plus de détails sur cette méthode .

Descripteur d'accÚs à la base de données (servlet PL / SQL)


Cette option est complĂštement similaire Ă  la prĂ©cĂ©dente, seule la procĂ©dure stockĂ©e PL / SQL agit comme gestionnaire de requĂȘtes.

Exemple d'URL - le nom du package, le nom de la procĂ©dure, les paramĂštres (requĂȘte GET) sont indiquĂ©s:

GET http://<server>:<port>/servlet_plsql/pi_test.test_serv?p_path=ppp 

Dans le cas d'une requĂȘte POST, les noms des paramĂštres doivent ĂȘtre saisis directement dans le corps de la requĂȘte via le signe «=», ce qui est plutĂŽt gĂȘnant, car le type du contenu de la requĂȘte (ContentType) dans ce cas ne peut ĂȘtre que du texte. Vous pouvez transfĂ©rer une structure xml ou json uniquement sous cette forme:

p_proc_param_name=<xml_data>
</xml_data>

Cette version du service Web n'est applicable que dans les cas oĂč nous traitons des demandes trĂšs simples - appels de procĂ©dure avec des types de donnĂ©es simples. La transmission de toute structure complexe Ă  plusieurs niveaux dans cette option ne fonctionnera pas.

Cette approche est décrite en détail sur le site Internet ORACLE-BASE.

Conclusion


La crĂ©ation d'un service Web dans Oracle est une tĂąche assez simple qui ne nĂ©cessite pas d'Ă©crire n'importe quel type de code super complexe. Dans le mĂȘme temps, les dĂ©veloppeurs Oracle intĂšgrent dans leur arsenal un mĂ©canisme assez puissant qui vous permet d'intĂ©grer des systĂšmes hĂ©tĂ©rogĂšnes ou des parties de systĂšmes via HTTP.

Dans cet article, nous avons examiné quatre approches pour créer des services Web.

Native Oracle WS est une technologie obsolÚte qui a néanmoins ses avantages: WSDL généré automatiquement, analyse automatique de XML, pas besoin d'installer de logiciel supplémentaire. Le principal inconvénient est la faible performance et la limitation des types de données pris en charge.

ORDS- à mon avis, la façon préférée de créer des services Web. Assez flexible et polyvalent. Parmi les inconvénients de cette méthode, nous pouvons seulement distinguer qu'elle n'est pas incluse dans le package Oracle standard, c'est-à-dire qu'elle nécessite une installation distincte.

Java Servlet est un moyen complĂštement universel qui ne nĂ©cessite pas l'installation de logiciels supplĂ©mentaires. Cependant, tout doit ĂȘtre fait entiĂšrement manuellement, car il n'y a aucune possibilitĂ© de services de gĂ©nĂ©ration automatique.

PL / SQL Servlet est l'approche la moins réussie. Parmi les avantages, nous pouvons distinguer que dans cette option, nous avons la possibilité d'appeler des procédures stockées via HTTP sans avoir besoin d'installer de logiciel supplémentaire, ou sans écrire de code supplémentaire dans d'autres langues: tout le code est écrit uniquement en PL / SQL.

Merci à tous pour votre attention! J'espÚre que l'article sera utile à ceux qui sont en quelque sorte connectés aux produits Oracle et sont perplexes face aux problÚmes d'intégration intra-systÚme et intersystÚmes.


All Articles