Webdienste in Oracle



Internetdiensteweit verbreitet für die Integration zwischen Komponenten eines Systems oder zwischen verschiedenen Systemen. Die Popularität von Webdiensten als Integrationsmöglichkeit beruht auf ihrer Vielseitigkeit sowie der einfachen Implementierung und dem Debugging. Vielseitigkeit ist mit der Datenübertragung über das Internet und das HTTP-Protokoll verbunden. Webdienste machen es relativ einfach, Integrationen zwischen Komponenten zu erstellen, die in verschiedenen Sprachen geschrieben sind und auf verschiedenen Betriebssystemen und Plattformen ausgeführt werden. Die einfache Implementierung von Webdiensten wird durch integrierte Tools und Komponenten in vielen IDEs erreicht, mit denen Sie sowohl den Webdienst (Anbieterseite) als auch den erforderlichen Code zum Aufrufen des Dienstes auf der Clientseite schnell entwickeln können. Debugging-Dienste werden durch die Verwendung von lesbaren Datenaustauschformaten - XML ​​und JSON - vereinfacht. Außerdem,Es gibt viele Dienstprogramme zum Debuggen und Testen von Diensten, einschließlich Laden.

In diesem Artikel werden verschiedene Möglichkeiten zum Erstellen von Webdiensten direkt aus Oracle DBMS betrachtet, dh ohne Verwendung von Tools von Drittanbietern.

Inhalt

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)

Hintergrund


Gegeben: Informationsgeschäftssystem eines großen Vertriebsnetzes (ca. tausend Einzelhandelsgeschäfte), bestehend aus vielen Komponenten und Subsystemen. In jedem Geschäft befindet sich ein Hauptserver - eine Oracle-Datenbank mit der Hauptgeschäftslogik. Geldknoten werden von einer separaten Software aus ihrer lokalen Datenbank verwaltet. Diese Software sammelt regelmäßig Daten vom Hauptserver (über WS SOAP) und gibt die Ergebnisse des Verkaufs zurück (Dateiaustausch).

Der Fortschritt blieb nicht stehen und neue Geräte erschienen in den Läden. Daten von diesem Gerät sollten regelmäßig an den Hauptserver des Geschäfts gesendet werden (Zeitraum - alle paar Minuten). Die Integration muss unbedingt über den Webdienst erfolgen. Die Nachricht muss ein bestimmtes Format haben. Eine Authentifizierung ist nicht erforderlich. Wir haben uns die Datenaustauschverträge angesehen und festgestellt, dass die verwendete Technologie von Webdiensten keine Integration von Gebäuden in solche Geräte ermöglicht. Und die Suche nach einer Lösung begann ...

Infolgedessen wurden mehrere Optionen für die Implementierung des erforderlichen Webdienstes in Betracht gezogen, bis eine separate Komponente geschrieben wurde, die ein Fenster für die Oracle-Datenbank für die Oracle-Datenbank öffnen würde: Zum einen würde ein Webdienst bereitgestellt, zum anderen würde über JDBC mit der Datenbank interagiert. Die Schwierigkeit besteht darin, dass die neue Komponente zum einen in tausend Filialen installiert werden müsste und zum anderen ein weiterer Link aufgetaucht wäre, der begleitet werden müsste. Daher war die Priorität weiterhin die Option, einen Webdienst mit integrierten Oracle-Tools zu implementieren.

Als Ergebnis der Suche haben wir vier Möglichkeiten gefunden, die wir in diesem Artikel berücksichtigen werden:

  1. Native Oracle XML DB-Webdienste
  2. Oracle REST Data Service
  3. Java Servlet
  4. Datenbankzugriffsdeskriptor (PL / SQL-Servlet)

Die ersten beiden Optionen werden genauer betrachtet. Ursprünglich wurden in unserem System native Oracle XML DB-Webdienste verwendet, dh sie wurden sozusagen vererbt. ORDS wurde ein Ersatz für diese veraltete Technologie (trotz der Tatsache, dass ich immer noch hart arbeiten und ORDS in tausend Geschäften installieren musste).

Zwei weitere Methoden - Java Servlet und PL / SQL Servlet - haben wir zusammen mit ORDS bei der Suche nach einer Alternative zu Native Oracle WS in Betracht gezogen, diese jedoch im Projekt nicht verwendet. Daher werden wir diese Ansätze nicht im Detail betrachten und uns auf eine kurze Referenz beschränken.

Der Artikel enthält einige praktische Beispiele für die Implementierung von Webdiensten mit Anweisungen zum Erstellen eines funktionierenden Dienstes.

Native Oracle XML DB-Webdienste


Fähigkeiten


Ermöglicht das Organisieren des Zugriffs auf die Oracle-Datenbank über HTTP mithilfe von WS SOAP (Version 1.1):

  • SQL- XQuery- SOAP.
  • ( ).



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



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

Es ist zu beachten, dass für alle Anforderungen an den Webdienst eine Authentifizierung erforderlich ist (aus der Dokumentation : Basisauthentifizierung: Oracle XML DB unterstützt die Standardauthentifizierung, bei der ein Client den Benutzernamen und das Kennwort im Klartext im Autorisierungsheader sendet). In Oracle können Sie den anonymen Zugriff auf Serverressourcen über HTTP konfigurieren - mithilfe des Oracle XML DB Protocol Server- Setups . Tatsächlich funktioniert dies jedoch nur für GET-Anforderungen, und für POST-Anforderungen ist eine Authentifizierung erforderlich. Da Native Oracle WS nur über POST-Anforderungen funktioniert, kann der anonyme Zugriff für diese Technologie nicht konfiguriert werden.

Anpassung


Um Native Oracle WS verwenden zu können, benötigen Sie:

  1. Konfigurieren Sie den integrierten HTTP-Server in Oracle.
  2. Konfigurieren Sie den Zugriff in der Oracle-Datenbank (öffnen Sie den HTTP-Port).
  3. Erstellen Sie ein Servlet.
  4. Konfigurieren Sie die ACL (Zugriffsliste).

Konfigurieren Sie den Oracle XML DB HTTP-Server


Der HTTP-Server sollte bereits standardmäßig funktionieren. In einigen Fällen ist jedoch möglicherweise eine zusätzliche Listener-Konfiguration erforderlich, mit der DESCRIPTION_LIST der folgende Block hinzugefügt wird:

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

Danach müssen Sie den Listener neu starten.

Konfigurieren Sie den HTTP-Zugriff


  1. Überprüfen des aktuellen Ports auf HTTP.

    SELECT dbms_xdb.gethttpport() AS http_port FROM dual;

    Der Wert "0" bedeutet, dass der HTTP-Zugriff deaktiviert ist.
  2. Port-Setup.

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

Erstellen eines Servlets für einen Webdienst


Damit der Webdienst funktioniert, ist in der Datenbankkonfiguration eine Servlet-Registrierung erforderlich.

Skript zum Erstellen eines Servlets
--   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;
/

Konfigurieren Sie die Zugriffsliste


Um über HTTP auf Oracle zuzugreifen, müssen Sie der DBMS-Konfiguration Regeln hinzufügen. Dies erfolgt mithilfe der integrierten DBMS-Dienstprogramme.

Um die ACL zu konfigurieren, benötigen Sie:

  • Skript zur Bearbeitung der Datenbankkonfiguration (unten);
  • Datenbankschema, für das die Konfiguration durchgeführt wird.

Das heißt, das Datenbankschema, für das die ACL konfiguriert wird, muss bereits erstellt sein. In den folgenden Beispielen finden Sie Verweise auf diesen Abschnitt an den Stellen, an denen Sie neue Datenbankschemata erstellen müssen. Für diese müssen Sie die ACL konfigurieren.

Im SYS-Schema führen wir das ACL-Konfigurationsskript aus:
--   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;
/

Es sollte sofort beachtet werden, dass eine ACL-Konfiguration erforderlich ist, wenn nicht nur Native Oracle WS, sondern auch alle anderen in diesem Artikel beschriebenen Methoden zum Erstellen von Webdiensten verwendet werden.

Webdienstbeispiel mit einer Stapelprozedur


Wir brauchen:

  • Das Datenbankschema, in dem sich die Objekte zur Verarbeitung von Webdienstanforderungen befinden.
  • Tabelle für die Protokollierung.
  • Paket mit Prozedur / Funktion.
  • Jedes Tool, mit dem Sie Webanfragen senden können. In diesem Fall wurde die SOAP-UI- Anwendung verwendet , Sie können jedoch bis zur Befehlszeile ein anderes Tool auswählen.

Eigenschaften:

  • Prozedurparameter müssen entweder einfache oder Objekttypen haben. Andernfalls wird die Prozedur nicht als Webdienstmethode wahrgenommen und nicht in die Liste der Dienstmethoden aufgenommen.
  • Um komplexe Strukturen von Eingabe- oder Ausgabedaten zu implementieren, müssen Sie Objekttypen verwenden (Stapeltypen können nicht verwendet werden).

Wir erstellen die notwendigen Datenbankobjekte:

  1. Schema WS_TEST:

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

    Fügen Sie der ACL sofort ein neues Schema hinzu. Das Skript im vorherigen Abschnitt.
  2. Erstellen Sie im neuen Schema eine Tabelle für die Protokollierung 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. Paket mit einem einfachen Verfahren:

    
    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;
    /

Der einfachste Webdienst wird erstellt und ist sofort einsatzbereit.

Um auf den Dienst zugreifen zu können, müssen Sie die URL im folgenden Format verwenden:

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

Wobei:

[Server] - Domänenname oder IP-Adresse des Oracle-Datenbankservers
[Port] - Port für den Zugriff über HTTP im Abschnitt "Konfigurieren des Zugriffs über HTTP"
[Servlet- Name ] - Name des Servlets im Abschnitt "Erstellen eines Servlets für das Web" service ”
[DB_SCHEMA] - Name des Datenbankschemas (in Großbuchstaben)
[WS_OBJ] - Name des Dienstes (in Großbuchstaben), der in unserem Fall dem Namen des Datenbankobjekts entspricht - der Name des Pakets

Beachten Sie, dass die URL wichtig ist!

Linkbeispiel:

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

Wenn wir im Browser auf diesen Link klicken, werden wir automatisch basierend auf unserem WSDL-Paket erstellt:

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>

Erstellen Sie zum Testen des Dienstes ein neues SOAP-Projekt in der SOAP-Benutzeroberfläche. Geben Sie als URL die Adresse aus dem obigen Beispiel an.

Beim Öffnen sehen Request 1wir, dass die Anforderungsvorlage bereits automatisch von der angegebenen WSDL generiert wird.

Fügen Sie sofort die Basisautorisierung für die Anforderung hinzu - Anmeldung und Kennwort sind dieselben wie beim Herstellen einer Verbindung zur Datenbank.



Beispielanforderung und Antwort. Bitte beachten Sie, dass der automatisch generierten Anfrage eine Zeile hinzugefügt wurde <pk:O_RESULT-VARCHAR2-OUT/>. Tatsache ist, dass es in Oracle 12c einen Fehler gibt: OUT-Variablen werden der WSDL für Native Oracle WS nicht hinzugefügt.



Das Ergebnis des Aufrufs ist in der Protokolltabelle sichtbar.



Ergebnisse


Die native Oracle XML DB-Webdiensttechnologie kann als industrielle Lösung verwendet werden, sofern dieser Webdienst nicht stark belastet wird (eine Anforderung in wenigen Sekunden). Diese Option ist geeignet, wenn Verbraucher keine strengen Anforderungen an einen Webdienst (dessen Attribute, Datenstrukturen, Verarbeitungslogik) haben und kein strikt vorgegebener Vertrag besteht. Wenn Sie einen Webdienst gemäß einer vordefinierten WSDL erstellen müssen (wie in unserem Fall mit neuen Geräten), ist die native Oracle WS-Technologie ungeeignet.

Oracle REST Data Service


Ab Version 11.1 führte Oracle die vollständige RESTful-Unterstützung in Form eines separaten Moduls namens Oracle REST Data Service (ORDS) ein.

ORDS ist eine Java-Anwendung, mit der Sie mithilfe von SQL und PL / SQL eine RESTful-API für eine Oracle-Datenbank erstellen können. Es ist eine Alternative zur Verwendung von Oracle HTTP Server und mod_plsql. Im Wesentlichen ist ORDS eine HTTP-Schnittstelle zwischen der Außenwelt und einer Oracle-Datenbank. Über diese Schnittstelle können Sie eingehende HTTP-Anforderungen an jedes Datenbankobjekt schließen - eine Tabelle oder eine PL / SQL-Prozedur.

Sie müssen lediglich ORDS für die erforderliche Datenbank installieren, konfigurieren und ausführen. Der weitere Prozess zum Erstellen von REST-Services besteht darin, Code in PL / SQL zu schreiben (oder sogar durch Klicken mit der Maus in der IDE, wenn der Code zu faul zum Schreiben ist).

Für die Installation von ORDS sind keine zusätzlichen Lizenzen erforderlich.

Bedarf:

  • Java JDK 8 oder höher;
  • Oracle 11.1 oder höher (Oracle 11 XE Release 2 wird ebenfalls unterstützt).

Es werden verschiedene ORDS-Bereitstellungsoptionen unterstützt:

  • Standalone-Modus;
  • auf dem Anwendungsserver (Oracle WebLogic Server, Apache Tomcat).

Fähigkeiten


Mit ORDS können Sie:

  • Organisieren Sie den Zugriff auf Ressourcen in einem RESTful-Stil.
  • Erstellen Sie eine Interaktion im Stil von "Remote Procedure Call" (Interaktion im RPC-Stil).

Einfach ausgedrückt, können Sie mit Hilfe von ORDS den Zugriff über HTTP auf bestimmte Datenbankobjekte öffnen - Tabellen, Prozeduren, Funktionen, Pakete.

Im ersten Fall handelt es sich um Ressourcen in dem Sinne, dass sie im RESTful-Architekturstil verstanden werden. Jede Ressource wird durch einen eindeutigen URI definiert, und Operationen mit Ressourcen (CRUD - Erstellen, Lesen, Ändern, Löschen) werden durch Operationen aus der HTTP-Anforderung bestimmt: PUT, POST, GET, DELETE. Wenn die Ressource beispielsweise ein Eintrag in der Mitarbeitertabelle ist, ist dieser Eintrag über eine URI des Formulars verfügbar:

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

Hier werden der Name des Datenbankschemas, der Tabellenname und die Datensatz-ID in der Tabelle in der URI angegeben. Somit führt diese HTTP-Anforderung tatsächlich eine SELECT-Operation aus der angegebenen Tabelle aus. Bei anderen Vorgängen (Hinzufügen, Ändern, Löschen) ist das Kommunikationsprinzip dasselbe: Der Pfad zur Ressource wird im URI angegeben, und zusätzliche Parameter werden im Anforderungshauptteil angegeben, z. B. die Feldwerte zum Einfügen des Datensatzes in die Tabelle.

Im zweiten Fall wird anstelle des Zugriffs auf die Ressource direkt ein Prozeduraufruf verwendet, der alles wie im ersten Fall (CRUD) ausführen und jede andere Logik ausführen kann, die den erforderlichen Geschäftsprozess implementiert. Ein Prozeduraufruf von einem Paket kann unter Verwendung einer HTTP-Anforderung dieses Formats erfolgen:

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

Parameter für die Prozedur werden im Anforderungshauptteil in Form von JSON-Formatstrukturen übertragen {"param" : "value"}. Der gleiche Ansatz wird bei der Verwendung des oben beschriebenen nativen Oracle WS verwendet, bei REST-Diensten gibt es jedoch keine Einschränkungen durch das SOAP-Protokoll.

Profis

  • Ein flexibler Mechanismus, mit dem Sie Webdienste beliebiger Komplexität implementieren können.
  • Einfache Implementierung: Um eine PL / SQL-Prozedur in einen Webdienst umzuwandeln, müssen Sie nur einige typische Befehle ausführen. Mit SQL Developer wird das Erstellen einer REST-API zu einem Mausklick mit einem Minimum an Code.
  • Die Möglichkeit, einen Webdienst ohne Authentifizierung zu implementieren.

Minus

  • ORDS ist nicht im Standardpaket von Oracle enthalten - es muss für jeden Server separat installiert werden (zusätzliche Lizenzen sind, wie bereits erwähnt, nicht erforderlich). Dies kann ein Problem sein, wenn Sie Tausende von Datenbankservern haben.

Anpassung


ORDS kann in zwei Modi gestartet werden: über den Anwendungsserver oder im Standalone-Modus.

In diesem Artikel wird nur die Option zum Ausführen im Standalone-Modus erläutert.

Damit ORDS funktioniert, benötigen Sie:

  1. Konfigurieren Sie die Einstellungen vor der Installation.
  2. Schließen Sie die ODRS-Installation ab.
  3. Starten Sie ORDS.
  4. Konfigurieren Sie die ACL (für das gewünschte Datenbankschema).

die Einstellungen


Die ORDS-Distribution verfügt standardmäßig über eine Datei mit folgenden Parametern:

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

Eine Beschreibung der Parameter finden Sie in der Dokumentation

Parameter für den Standalone-Modus:
ParameterBeschreibung
db.hostnameName oder IP-Adresse des Oracle-Datenbankservers
db.portDB-Port (z. B. 1521)
db.servicenameServicename-Datenbank
db.usernameDer Benutzername des PL / SQL-Gateways. Standard = APEX_PUBLIC_USER, aber das Beispiel plant nicht die Verwendung von APEX, sodass Sie diesen Parameter leer lassen können
db.passwordBenutzerpasswort (auch nicht ausfüllen)
migrate.apex.restÜbergang von RESTful APEX-Diensten zu ORDS. Auf false setzen, wenn APEX nicht verwendet wird.
rest.services.apex.addKonfigurieren Sie ORDS für die Verwendung in APEX
rest.services.ords.addLegen Sie das Datenbankschema für ORDS fest (ORDS_PUBLIC_USER und ORDS_METADATA). Wert muss wahr sein
schema.tablespace.defaultStandardtabellenbereich für das ORDS_METADATA-Schema
schema.tablespace.tempTemporärer Tabellenbereich für das ORDS_METADATA-Schema
standalone.http.portDer Port, auf dem ORDS ausgeführt wird. Dieser Port wird im URI für den Zugriff auf WS verwendet.
user.tablespace.defaultStandardtabellenbereich für das Schema ORDS_PUBLIC_USER
user.tablespace.tempTemporärer Tabellenbereich für das Schema ORDS_PUBLIC_USER
Daher sollte der Inhalt der Datei ungefähr so ​​aussehen:

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

Wenn die erforderlichen Einstellungen abgeschlossen sind, können Sie mit der Installation fortfahren.

Installation


Wir führen den Befehl im Betriebssystem aus:

java -jar ords.war

Standardmäßig wird die Konfigurationsdatei aus dem Verzeichnis paramsneben übernommen ords.war. Sie können den Pfad zu dieser Datei explizit mit dem folgenden Parameter angeben --parameterFile:

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

Gehen Sie im Installationsdialog wie folgt vor:

  1. Wir geben den Pfad zum Verzeichnis zum Speichern der Konfiguration an (in dem angegebenen Beispiel wird conf als Ergebnis in demselben Verzeichnis, in dem sich die Datei befindet ords.war, ein Verzeichnis erstellt, confin dem die Dateien mit der ORDS-Konfiguration erstellt werden).
  2. Nachdem der Befehl Datenbankkennwort für ORDS_PUBLIC_USER eingeben angezeigt wird, geben wir das Kennwort für das Schema ein ORDS_PUBLIC_USER. Unter diesem Benutzer stellt ORDS eine Verbindung zur Datenbank her.
  3. Nach der Eingabeaufforderung Geben Sie 1 ein, wenn Sie PL / SQL Gateway verwenden möchten, oder 2, um diesen Schritt zu überspringen. Wir antworten mit „2“, da wir APEX nicht verwenden und nicht migrieren müssen mod_plsql.
  4. Nach der Anweisung Geben Sie 1 ein, wenn Sie im Standalone-Modus starten möchten, oder 2, um [1] zu beenden, und antworten Sie mit „1“.
  5. Nach der Anweisung Geben Sie 1 ein, wenn Sie HTTP verwenden, oder 2, wenn Sie HTTPS verwenden [1]. Wir antworten 1.

Installationsdialog
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)

Infolgedessen wird ein Verzeichnis mit der ORDS-Konfiguration erstellt und Dienstprogrammschemata für ORDS werden in der Datenbank angezeigt.

Sehen Außerdem: Installieren Sie Oracle REST Data Services 3.0.X in weniger als 5 Minuten .

Starten


Das Starten im Standalone-Modus wird mit dem folgenden Befehl ausgeführt:

java -jar ords.war standalone

Dialog starten
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

Danach ist ORDS betriebsbereit. Die Webdienstadresse lautet http: // <Hostname>: / ords / ..., wobei <Hostname> der Name des Computers ist, auf dem ORDS ausgeführt wird (er muss nicht mit dem Namen des Datenbankservers übereinstimmen, dh ORDS kann auf einem anderen Host ausgeführt werden ), <Port> - der in der ORDS-Konfiguration angegebene Port.

Wenn Sie möchten, können Sie ein Skript erstellen, um ORDS beim Start des Betriebssystems automatisch auszuführen.

Zugriffseinstellung


Der letzte Schritt besteht darin, die ACL zu konfigurieren. Die Schritte sind die gleichen wie bei der Verwendung von Native Oracle WS.

Sie müssen diesen Schritt ausführen, nachdem das Datenbankschema erstellt wurde. In den folgenden Beispielen wird daher separat angegeben, wann Sie diese Konfiguration durchführen müssen. Bisher können wir davon ausgehen, dass alle vorbereitenden Schritte abgeschlossen sind, und mit den Beispielen fortfahren.

Beispiel 1: Handler für eine POST-Anforderung


Betrachten Sie als Beispiel die Interaktionsimplementierungsoption im RPC-Stil. Das heißt, wir erstellen eine Webdienstmethode, deren Handler eine Stapelprozedur ist.

In dieser Version wurde die Arbeit mit ORDS in unserem Projekt für das Vertriebsnetz implementiert, und das Ergebnis entsprach den Erwartungen. Es stellte sich als schnelle und universelle Möglichkeit heraus, neue Methoden für Webdienste für verschiedene Geschäftsprozesse zu erstellen - von der Arbeit mit Geräten bis zur API für Websites.

Wie oben erwähnt, ist die ORDS-Unterstützung auch in SQL Developer (der von Oracle entwickelten Datenbank-IDE) enthalten. In SQL Developer ist das Erstellen von Webdiensten direkt über Menüelemente oder das Kontextmenü verfügbar.

In diesem Artikel werden Beispiele mit SQL Developer (Version 18) erstellt. Der PL / SQL-Code, der aufgrund von Aktionen in der IDE in der Datenbank ausgeführt wird, ist jedoch ebenfalls enthalten.

Die Version der Datenbank, in der die Experimente durchgeführt wurden:

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

Erstellen eines Testbenutzers für WS


Zum Beispiel brauchen wir wieder ein neues Schema - erstellen Sie es:

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

Einrichten eines Datenbankschemas


Nachdem das Diagramm erstellt wurde, muss es über ORDS zugänglich gemacht werden.

Dafür:

  1. Erstellen Sie in SQL Developer eine Verbindung für WS_TEST.
  2. Rufen Sie in der Liste der Verbindungen das Kontextmenü für die neue Verbindung auf. Wählen Sie REST Services → REST Services aktivieren ... :


  3. Aktivieren Sie im Dialogfeld das Kontrollkästchen neben Schema aktivieren (Sie können hier auch den Parameter " Schema-Alias " ändern, wenn anstelle des Schemanamens ws_testanderer Text im URI angezeigt werden soll):


  4. Wenn Sie auf "Weiter" klicken , wird der PL / SQL-Code angezeigt, der eventuell in der Datenbank ausgeführt wird (und den Sie selbst schreiben können, ohne die IDE zu verwenden):



Listing:

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;
/

Modul und Vorlage erstellen


Als Nächstes müssen Sie ein Modul und eine Vorlage für die Ressource erstellen.

Ein Modul ist eine strukturelle Einheit, mit der Sie mehrere logisch zusammengehörige Ressourcenvorlagen gruppieren können.

Eine Vorlage ist ein bestimmter Webdienst, der bestimmte Methoden für eine Ressource bereitstellt.

An der Quelle :

Ressourcenmodul: Eine Organisationseinheit, mit der verwandte Ressourcenvorlagen gruppiert werden.

Ressourcenvorlage: Ein einzelner RESTful-Service, der Anforderungen für bestimmte URIs (Universal Resource Identifiers) bearbeiten kann. Der Satz von URIs wird durch das URI-Muster der Ressourcenvorlage definiert.


Für einen Online-Shop kann beispielsweise ein Modul aufgerufen werdenshop - In diesem Modul werden alle APIs des Geschäfts kombiniert. Die Vorlagen können bestimmte Ressourcen sein, z. B. eine Bestellung (Vorlage order), ein Produktkatalog (Vorlage item), eine Zahlung (Vorlage payment) usw.

Um ein Modul und eine Vorlage zu erstellen, müssen Sie die folgenden Schritte ausführen:

  1. Öffnen Sie in der Objektstruktur den Abschnitt REST Data Services, rufen Sie das Kontextmenü im Abschnitt Module auf , wählen Sie Neues Modul ... :


  2. Geben Sie im Dialogfeld zur Modulerstellung den Modulnamen ( shop) und den Präfix-URI an (wir geben auch an shop - im folgenden Beispiel sehen wir sofort, wie die Webdienst-Adressvorlage aussehen wird), setzen Sie eine Morgendämmerung vor " Veröffentlichen" und klicken Sie auf "Weiter>" :


  3. Geben Sie im nächsten Dialogfeld beispielsweise den Namen der Vorlage an orderund klicken Sie erneut auf "Weiter>" .

    Im letzten Dialog sehen wir alle eingegebenen Parameter des Moduls und der Vorlage. Auf der Registerkarte SQL sehen Sie den PL / SQL-Code, der in der Datenbank ausgeführt wird, wenn Sie auf Fertig stellen klicken :



Um ein Modul zu erstellen shop , können Sie mehr Muster hinzufügen - auch im Objektbaum, das Kontextmenü und wählen Sie die Vorlage hinzufügen ... .

Codeauflistung zum Erstellen eines Moduls und einer Vorlage
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;
/

Erstellen eines HTTP-Anforderungshandlers


Jetzt müssen wir einen HTTP-Anforderungshandler für unseren Service erstellen.

Zuerst müssen wir Datenbankobjekte erstellen, die die Anforderungsverarbeitungslogik enthalten.

Wir benötigen eine Tabelle für die Protokollierung und ein Paket, in dem sich ein Handlercode befindet.

Erstellen Sie eine Tabelle mit einem Skript:
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;

Erstellen Sie ein Paket:
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;
/

Für die erstellte Vorlage müssen Sie nun einen Handler hinzufügen. Fügen Sie einen Handler für die HTTP-Methode hinzu POST.

Führen Sie dazu die folgenden Schritte aus:

  1. Wir rufen das Kontextmenü für die Vorlage auf, wählen Add Handler und dann die HTTP-Methode:

  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;

    Bei Bedarf können Sie den PL / SQL-Code zum Erstellen eines Handlers abrufen. Wählen Sie dazu im Kontextmenü des ORDS-Moduls REST-Definition aus und geben Sie an, wo das Modulerstellungsskript beispielsweise in die Zwischenablage ausgegeben werden soll:


Der resultierende Code zum Erstellen des Moduls
-- 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;


Hinweis: Wenn Sie die Modulerstellung ORDS.DEFINE_MODULEerneut ausführen , werden alle Vorlagen dieses Moduls automatisch gelöscht, und es wird keine Warnung angezeigt!

Beispiel aufrufen


Hier ist unser Webservice bereit. Es bleibt seine Arbeit zu überprüfen.

Zur Überprüfung führen wir die Anfrage aus:

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" }

Als Antwort erhalten wir:

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

Das Ergebnis der Methodenausführung ist ein Datensatz mit dem Hauptteil der Anforderung und Antwort in der Protokolltabelle:



Wie Sie sehen können, wurde die gesendete HTTP-Anforderung von der Prozedur aus dem Paket erfolgreich verarbeitet.

Parameter aus der Anfrage


Oben haben wir bereits das Ergebnis eines einfachen Webdienstes gesehen. Lassen Sie uns nun die Aufgabe etwas komplizieren, indem wir der Anforderung zusätzliche Parameter hinzufügen.

Es gibt zwei Möglichkeiten, Parameter zu übergeben:

Über URL. Die Parameter werden in der URL im Standardformular festgelegt:

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

Über HEADER. Die Parameter werden im Anforderungsheader wie p1: val1

folgt festgelegt: In ORDS im Anforderungshandler werden Parameter als Bindevariablen definiert.

Wir fügen dem vorherigen Beispiel zwei Parameter hinzu: prm1- Parameter im URI, prm2- Parameter im Anforderungsheader.

Um diese Parameter zu verarbeiten, PK_ORDS_API.process_request:fügen wir die Prozedur hinzu, fügen die Parameter hinzu a_prm_uriund a_prm_hdr, zu denen die Werte unserer Parameter aus der Anforderung kommen.

Request-Handler-Prozedur mit neuen Parametern
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;

Innerhalb der Prozedur zeichnen wir einfach die Werte der neuen Parameter im Protokoll auf.

Fügen Sie dem POST-Anforderungshandler neue Parameter hinzu - in Form von Bindevariablen :prm_uriund :prm_hdr.

Handler der POST-Anforderungsanforderung mit neuen Parametern:

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;

Im Handler auf dem Parameter Registerkarte deklariert die Variablen:


In dieser Form das erste Feld ( Name der ) enthält den Namen des Parameters, der in der Anforderung, das zweite Feld (erwartet wird Bind Parameter ) - der Name der Bind - Variablen , die in der Prozedur dieser Anfrage angegeben werden.

Lassen Sie uns die Anforderung mit neuen Parametern ausführen:



Ergebnis - Die Parameter aus der Anforderung wurden im Protokoll gespeichert:


Bitte beachten Sie, dass die Parameter aus dem URI auch aus der CGI-Variablen abgerufen werden QUERY_STRINGkönnen, dh um die Parameter abzurufen, müssen die Bindevariablen nicht gestartet werden. Sie können sie in der Handler-Prozedur analysieren Anfrage.

CGI-Variablen


Bei der Arbeit mit HTTP in Oracle können die Werte von Umgebungsvariablen abgerufen werden, die den Kontext der HTTP-Anforderung widerspiegeln. Mit der Prozedur können Sie die Werte von Variablen abrufen OWA_UTIL.get_cgi_env.

Liste der in PL / SQL verfügbaren CGI-Variablen
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

Siehe auch: HTTP-Header (OWA_UTIL) und ORDS-spezifische Bindungsvariablen

Beispiel 2: Zugriff auf eine Tabelle über ORDS


In diesem Beispiel betrachten wir die Organisation des Zugriffs auf ein Datenbankobjekt (auf eine Tabelle) über ORDS.

Wie im vorherigen Beispiel machen wir den Zugriff ohne Autorisierung. Informationen zum sicheren Zugriff auf Ressourcen finden Sie in der Dokumentation .

Um ein Datenbankobjekt über ORDS zugänglich zu machen, müssen Sie nur einen Schritt ausführen - den Befehl ORDS.ENABLE_OBJECT. Danach kann über eine URI des Formulars auf das Objekt zugegriffen werden:

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

Erstellen Sie ein Testmuster


Als Beispiel erstellen wir die Tabelle "Bestellungen".

Skript zur Tabellenerstellung:

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;

Tabellenzugriff über ORDS öffnen


  1. In SQL Developer Rufen Sie das Kontextmenü für die gewünschte Tabelle, wählen Sie das den Dienst den REST aktiviert ... .



  2. Aktivieren Sie im Fenster mit den Zugriffseinstellungen das Kontrollkästchen Objekt aktivieren, deaktivieren Sie das Kontrollkästchen Autorisierung erforderlich , klicken Sie auf "Fertig stellen" (oder "Weiter" , um den empfangenen PL / SQL-Code anzuzeigen ):



  3. Nach Ausführung dieser Schritte wird die Tabelle T_ORDERüber HTTP verfügbar, den Basis-URI für den Zugriff auf die Ressource:

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

    Auflistung der Tabelleneinschlüsse:

    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;
    /


Erstellen oder bearbeiten Sie einen Datensatz


Der Zugriff auf die Tabelle ist offen. Wir prüfen, wie Sie über ORDS Datensätze in der Tabelle erstellen und bearbeiten können.

Um einen Datensatz zu erstellen, führen wir die Anforderung aus PUT.

In der ORDS-Dokumentation wird die folgende Beschreibung in der Methodenbeschreibung PUTangegeben:

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

Das heißt, das Feld KeyValues(Datensatzschlüssel) muss auch für die Erstellung eines neuen Datensatzes ausgefüllt werden. Die Abfrage selbst sollte alle Felder in der Tabelle auflisten (das Schlüsselfeld kann jedoch weggelassen werden).

Anfrage
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"
}

Als Antwort erhalten wir alle Felder des gerade erstellten Datensatzes:

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/"
      }
   ]
}

Wir sehen uns den Inhalt der Tabelle an - unser neuer Datensatz wurde angezeigt:



Um den Datensatz zu ändern, rufen wir dieselbe PUT-Methode auf. Ändern Sie den Hinweis in unserer Bestellung:

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.  "
}

In der Antwort erhalten wir denselben JSON mit den Parametern des geänderten Datensatzes. In der Tabelle sehen wir, dass der Hinweis aktualisiert wurde:



Datensätze aus einer Tabelle abrufen


Es gibt drei Modi zum Abfragen von Daten aus einer Tabelle:

  1. Seitenanfrage:

    GET http://<HOST>:<PORT>/ords/<SchemaAlias>/<ObjectAlias>/?offset=<Offset>&limit=<Limit>
  2. Anfrage für Bedingungen:

     GET http://<HOST>:<PORT>/ords/<SchemaAlias>/<ObjectAlias>/?q=<FilterClause>
  3. Primärschlüsselanforderung:

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

Um alle Datensätze abzurufen, können Sie die Abfrage ausführen, ohne Parameter anzugeben:

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

Antworten
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/"
      }
   ]
}

Es ist eine offene Frage, wie Oracle dazu gebracht wird, dem Content-Type-Header eine Codierung hinzuzufügen.

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

Antworten
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/"
      }
   ]
}

Aufzeichnung löschen


Verwenden Sie zum Löschen die HTTP-Methode DELETE.

Anfrage:

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

Die Anfrage in ihrer ursprünglichen Form:

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

Antworten:

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

Ergebnisse


ORDS ist ein ziemlich flexibler und universeller Mechanismus für die Arbeit mit Webdiensten, mit dem Sie ein vollwertiges REST implementieren können. In Bezug auf die Leistung ist es Native Oracle WS mit seiner umfangreichen internen XML-Analyse weit überlegen. Für die Implementierung eines hoch ausgelasteten Systems ist dieser Ansatz nicht geeignet: In diesem Fall wird ein anderer Technologie-Stack benötigt - ein separater Anwendungsserver, Proxy-Anforderungen, Verwendung von Clusterdatenbanken usw. Für die Implementierung von Systemen mit einer relativ geringen Anzahl von HTTP-Anforderungen (bis zu 10–20 pro Sekunde) ist ORDS jedoch der optimale Ansatz in Bezug auf Leistung und Flexibilität. ORDS ist Native Oracle WS nur in Bezug auf die Generierung einer Webdienstspezifikation unterlegen: Letzteres bietet eine vollständig fertige Spezifikation (WSDL), die den Verbrauchern des Dienstes "wie besehen" zur Verfügung gestellt werden kann. ORDS hat auch die FähigkeitGenerierung einer Beschreibung, aber für den in diesem Artikel betrachteten Ansatz mit einem vollständig universellen Dienst (wenn es ein gemeinsames Verarbeitungsverfahren für alle Dienste gibt) wird die automatische Generierung der Spezifikation unmöglich. Oracle generiert nur eine Spezifikation der obersten Ebene, und die Details (Datenmodelle) müssen manuell beschrieben werden.

Alternative Ansätze


Java Servlet


Diese Option zum Erstellen von Webdiensten in der Konfigurationsmethode ähnelt der von Native Oracle WS: Sie erfordert auch die Verwendung des integrierten HTTP-Servers von Oracle sowie ACL-Einstellungen (wie in der Tat alle anderen Methoden). Im Gegensatz zu Native Oracle WS funktioniert diese Option jedoch mit reinem HTTP. Request - Handler in diesem Fall sind in Java geschrieben und schauen nur auf dem HTTP-Anfrage - Typ ( PUT, GET, POST, und so weiter, obwohl sie und einen Handler für alle Arten getan werden kann), und die Verarbeitungslogik bleibt vollständig im Ermessen des Entwicklers. Sie können den Anforderungshauptteil "wie er ist" in die Datenbanklogik übertragen, ihn zerlegen und dort verarbeiten. Sie können einen Teil der Logik auf der Seite des Java-Handlers belassen und die gewünschte Prozedur aus der Datenbank aufrufen, abhängig von den Daten, die in der Anforderung eingegangen sind.

Dieser Ansatz für die Implementierung von Webdiensten ist sehr universell und erfordert auch keine Installation zusätzlicher Komponenten. Wir konnten es nicht nur aufgrund der strengen Anforderungen für den Dienst anwenden: Wir brauchten einen Webdienst, für den keine Authentifizierung erforderlich war. Bei der Implementierung dieses Ansatzes ist eine Authentifizierung erforderlich, die nicht umgangen werden kann.

Weitere Informationen zu dieser Methode finden Sie in der Oracle-Dokumentation .

Datenbankzugriffsdeskriptor (PL / SQL-Servlet)


Diese Option ist der vorherigen völlig ähnlich, nur die gespeicherte PL / SQL-Prozedur fungiert als Anforderungshandler.

Beispiel-URL - Der Paketname, der Prozedurname und die Parameter (GET-Anforderung) werden angegeben:

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

Bei einer POST-Anforderung müssen die Parameternamen über das Zeichen "=" direkt in den Anforderungshauptteil eingegeben werden, was ziemlich unpraktisch ist, da der Typ des Anforderungsinhalts (ContentType) in diesem Fall nur Text sein kann. Sie können eine XML- oder JSON-Struktur nur in dieser Form übertragen:

p_proc_param_name=<xml_data>…</xml_data>

Diese Version des Webdienstes ist nur in Fällen anwendbar, in denen es sich um sehr einfache Anforderungen handelt - Prozeduraufrufe mit einfachen Datentypen. Das Übertragen komplexer mehrstufiger Strukturen in dieser Option funktioniert nicht.

Dieser Ansatz wird auf der ORACLE-BASE-Website ausführlich beschrieben .

Fazit


Das Erstellen eines Webdienstes in Oracle ist eine recht einfache Aufgabe, für die kein superkomplexer Code geschrieben werden muss. Gleichzeitig erhalten Oracle-Entwickler einen ziemlich leistungsstarken Mechanismus in ihr Arsenal, mit dem Sie heterogene Systeme oder Systemteile über HTTP integrieren können.

In diesem Artikel haben wir vier Ansätze zum Erstellen von Webdiensten untersucht.

Native Oracle WS ist eine veraltete Technologie, die dennoch ihre Vorteile hat: automatisch generierte WSDL, automatisches Parsen von XML, keine Installation zusätzlicher Software. Der Hauptnachteil ist die geringe Leistung und Einschränkung der unterstützten Datentypen.

BESTELLUNGEN- Meiner Meinung nach der bevorzugte Weg, um Webdienste zu erstellen. Flexibel genug und vielseitig. Von den Unannehmlichkeiten dieser Methode können wir nur unterscheiden, dass sie nicht im Standardpaket von Oracle enthalten ist, dh eine separate Installation erfordert.

Java Servlet ist eine völlig universelle Methode, bei der keine zusätzliche Software installiert werden muss. Alles muss jedoch vollständig manuell erfolgen, da keine Möglichkeit zur automatischen Generierung von Diensten besteht.

PL / SQL-Servlet ist der am wenigsten erfolgreiche Ansatz. Von den Pluspunkten können wir unterscheiden, dass wir mit dieser Option gespeicherte Prozeduren über HTTP aufrufen können, ohne zusätzliche Software installieren zu müssen oder ohne zusätzlichen Code in anderen Sprachen zu schreiben: Der gesamte Code wird nur in PL / SQL geschrieben.

Vielen Dank für Ihre Aufmerksamkeit! Ich hoffe, dass das Material des Artikels für diejenigen nützlich sein wird, die irgendwie mit Oracle-Produkten verbunden sind und von den Problemen der systeminternen und systemübergreifenden Integration verwirrt sind.


All Articles