خدمات الويب في أوراكل



خدمات الويبتستخدم على نطاق واسع للتكامل بين مكونات نظام واحد أو بين أنظمة مختلفة. ترجع شعبية خدمات الويب كوسيلة للتكامل إلى تعدد استخداماتها ، فضلاً عن سهولة التنفيذ والتصحيح. ترتبط تعددية الاستخدامات بنقل البيانات باستخدام الإنترنت وبروتوكول HTTP. تجعل خدمات الويب من السهل نسبيًا إنشاء تكاملات بين المكونات المكتوبة بلغات مختلفة تعمل على أنظمة تشغيل وأنظمة تشغيل مختلفة. يتم تحقيق بساطة تنفيذ خدمات الويب من خلال الأدوات والمكونات المضمنة في العديد من IDEs التي تسمح لك بتطوير كل من خدمة الويب (جانب الموفر) والشفرة اللازمة للاتصال بالخدمة من جانب العميل (جانب العميل) بسرعة. يتم تبسيط خدمات تصحيح الأخطاء باستخدام تنسيقات تبادل البيانات التي يمكن قراءتها من قبل الإنسان - XML ​​و JSON. الى جانب ذلك ،هناك العديد من الأدوات المساعدة لخدمات التصحيح والاختبار ، بما في ذلك الحمل.

في هذه المقالة ، سننظر في عدة طرق لإنشاء خدمات الويب مباشرة من Oracle DBMS ، أي بدون استخدام أدوات الطرف الثالث.

المحتوى

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)

خلفية


إعطاء: نظام معلومات الأعمال لشبكة توزيع كبيرة (حوالي ألف متجر بيع بالتجزئة) ، يتألف من العديد من المكونات والأنظمة الفرعية. يوجد داخل كل متجر خادم رئيسي - قاعدة بيانات أوراكل مع منطق الأعمال الرئيسي. تتم إدارة العقد النقدية بواسطة برنامج منفصل من قاعدة البيانات المحلية الخاصة بهم. يقوم هذا البرنامج بشكل دوري بجمع البيانات من الخادم الرئيسي (عبر WS SOAP) ويعيد نتائج البيع (تبادل الملفات).

التقدم لم يقف ساكنا ، وظهرت معدات جديدة في المتاجر. يجب إرسال البيانات من هذا الجهاز بشكل دوري إلى الخادم الرئيسي للمخزن (الفترة - كل بضع دقائق) ، يجب أن يمر التكامل بالضرورة عبر خدمة الويب ، يجب أن يكون للرسالة تنسيق معين ، لا حاجة للمصادقة. نظرنا في عقود تبادل البيانات ووجدنا أن التكنولوجيا المستخدمة لخدمات الويب لن تسمح بتكامل البناء مع هذه المعدات. وبدأ البحث عن حل ...

ونتيجة لذلك ، تم النظر في العديد من الخيارات لتنفيذ خدمة الويب المطلوبة ، حتى كتابة مكون منفصل يفتح نافذة لقاعدة بيانات Oracle لقاعدة بيانات HTTP: من ناحية ، سيوفر خدمة ويب ، من ناحية أخرى ، سوف يتفاعل مع قاعدة البيانات عبر JDBC. تكمن الصعوبة في أن المكون الجديد ، أولاً ، يجب تثبيته في ألف متجر ، وثانيًا ، سيظهر رابط آخر يجب أن يكون مصحوبًا. لذلك ، لا تزال الأولوية هي خيار تنفيذ خدمة ويب باستخدام أدوات Oracle المدمجة.

نتيجة لعمليات البحث ، وجدنا أربع طرق سننظر فيها في هذه المقالة:

  1. خدمات الويب الأصلية من Oracle XML DB
  2. خدمة بيانات Oracle REST
  3. جافا سيرفلت
  4. واصف قاعدة البيانات (PL / SQL servlet)

سيتم النظر في الخيارين الأولين بمزيد من التفصيل. تم استخدام خدمات Oracle XML DB Web Services الأصلية في نظامنا في البداية ، أي أنها موروثة ، إذا جاز التعبير. أصبحت ORDS بديلاً لهذه التكنولوجيا القديمة (على الرغم من أنني ما زلت أعمل بجد وتثبيت ORDS في ألف متجر).

طريقتان أخريان - Java Servlet و PL / SQL Servlet - أخذنا بعين الاعتبار مع ORDS عند البحث عن بديل لـ Native Oracle WS ، لكننا لم نستخدمه في المشروع. لذلك ، لن ننظر في هذه الأساليب بالتفصيل ونقتصر على مرجع موجز.

ستقدم المقالة بعض الأمثلة العملية لتطبيق خدمات الويب مع تعليمات ستساعد في إنشاء خدمة عمل.

خدمات الويب الأصلية من Oracle XML DB


قدرات


يتيح لك تنظيم الوصول إلى قاعدة بيانات Oracle عبر HTTP باستخدام WS SOAP (الإصدار 1.1):

  • SQL- XQuery- SOAP.
  • ( ).



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



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

تجدر الإشارة إلى أن المصادقة مطلوبة لجميع الطلبات إلى خدمة الويب (من الوثائق : المصادقة الأساسية: يدعم Oracle XML DB المصادقة الأساسية ، حيث يرسل العميل اسم المستخدم وكلمة المرور بنص واضح في رأس المصادقة). في Oracle ، يمكنك تكوين وصول مجهول إلى موارد الخادم عبر HTTP - باستخدام تكوين خادم Oracle XML DB Protocol Server ، ولكنه في الواقع يعمل فقط لطلبات GET ، والمصادقة مطلوبة لطلبات POST. نظرًا لأن Native Oracle WS يعمل فقط من خلال طلبات POST ، فلا توجد طريقة لتكوين الوصول المجهول لهذه التقنية.

التخصيص


لاستخدام Oracle WS الأصلي ، ستحتاج إلى:

  1. قم بتكوين خادم HTTP المضمن في Oracle.
  2. تكوين الوصول داخل قاعدة بيانات Oracle (افتح منفذ HTTP).
  3. قم بإنشاء servlet.
  4. تكوين ACL (قائمة الوصول).

تكوين خادم Oracle XML DB HTTP


يجب أن يعمل خادم HTTP بالفعل افتراضيًا بالفعل ، ولكن في بعض الحالات قد يلزم تكوين مستمع إضافي - إضافة الكتلة التالية إلى DESCRIPTION_LIST:

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

بعد ذلك ، تحتاج إلى إعادة تشغيل المستمع.

تكوين وصول HTTP


  1. التحقق من المنفذ الحالي لبروتوكول HTTP.

    SELECT dbms_xdb.gethttpport() AS http_port FROM dual;

    تعني القيمة "0" أنه تم تعطيل وصول HTTP.
  2. إعداد المنفذ.

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

تكوين servlet لخدمة الانترنت


لكي تعمل خدمة الويب ، مطلوب تسجيل servlet في تكوين قاعدة البيانات.

سكريبت لإنشاء 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;
/

تكوين قائمة الوصول


للوصول إلى Oracle من خلال HTTP ، تحتاج إلى إضافة قواعد في تكوين DBMS. يتم ذلك باستخدام أدوات DBMS المضمنة.

لتكوين قائمة التحكم بالوصول (ACL) ، ستحتاج إلى:

  • البرنامج النصي تحرير تكوين قاعدة البيانات (أدناه) ؛
  • مخطط قاعدة البيانات الذي يتم التكوين من أجله.

بمعنى ، يجب إنشاء مخطط قاعدة البيانات التي يتم تكوين ACL لها. في الأمثلة أدناه ، ستكون هناك مراجع لهذا القسم ، في تلك الأماكن حيث تحتاج إلى إنشاء مخططات قاعدة بيانات جديدة - بالنسبة لهم ، ستحتاج إلى تكوين ACL.

في مخطط SYS ، نقوم بتنفيذ البرنامج النصي لتكوين 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;
/

وتجدر الإشارة على الفور إلى أن تكوين ACL مطلوب عند استخدام ليس فقط Oracle WS الأصلي ، ولكن أيضًا جميع الطرق الأخرى لإنشاء خدمات الويب التي تمت مناقشتها في هذه المقالة.

مثال على خدمة الويب باستخدام إجراء دفعي


سنحتاج إلى:

  • مخطط قاعدة البيانات الذي سيتم ايجاد العناصر لمعالجة طلبات خدمات الانترنت فيه.
  • جدول لتسجيل الدخول.
  • حزمة مع الإجراء / الوظيفة.
  • أي أداة تسمح لك بإرسال طلبات الويب. في هذه الحالة ، تم استخدام تطبيق SOAP UI ، ولكن يمكنك اختيار أي أداة أخرى ، حتى سطر الأوامر.

الميزات:

  • يجب أن يكون لمعلمات الإجراء إما أنواع بسيطة أو أنواع الكائنات. وبخلاف ذلك ، لن يُنظر إلى الإجراء كطريقة خدمة ويب ولن يتم تضمينه في قائمة طرق الخدمة.
  • لتنفيذ الهياكل المعقدة لبيانات الإدخال أو الإخراج ، تحتاج إلى استخدام أنواع الكائنات (لا يمكن استخدام أنواع الدُفعات).

نقوم بإنشاء كائنات قاعدة البيانات اللازمة:

  1. مخطط WS_TEST:

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

    قم بإضافة مخطط جديد إلى ACL على الفور. البرنامج النصي في القسم السابق.
  2. في المخطط الجديد ، قم بإنشاء جدول للتسجيل 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. رزمة مع إجراء بسيط:

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

أبسط خدمة ويب تم إنشاؤها وجاهزة للعمل.

للوصول إلى الخدمة ، تحتاج إلى استخدام URL بالتنسيق التالي:

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

حيث:

[server] - اسم المجال أو عنوان IP لخادم قاعدة بيانات Oracle
[port] - منفذ للوصول عبر HTTP المحدد في القسم "تكوين الوصول عبر HTTP"
[servlet_name] - اسم الخادم المحدد في القسم "إنشاء servlet للويب خدمة "
[DB_SCHEMA] - اسم مخطط قاعدة البيانات (في الحالة العليا)
[WS_OBJ] - اسم الخدمة (في الحالة العليا) ، وهو ما يعادل اسم كائن قاعدة البيانات ، في حالتنا - اسم الحزمة

لاحظ أن عنوان URL مهم!

مثال الارتباط:

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

إذا نقرنا على هذا الرابط في المتصفح ، فسيتم إنشاؤه تلقائيًا بناءً على حزمة 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>

لاختبار الخدمة ، قم بإنشاء مشروع SOAP جديد في واجهة مستخدم SOAP. كعنوان URL ، حدد العنوان من المثال أعلاه.

عند الفتح ، Request 1نرى أن قالب الطلب يتم إنشاؤه تلقائيًا تلقائيًا بواسطة WSDL المحدد.

قم بإضافة التفويض الأساسي للطلب على الفور - تسجيل الدخول وكلمة المرور هي نفسها عند الاتصال بقاعدة البيانات.



طلب مثال والاستجابة. يرجى ملاحظة أنه تمت إضافة خط إلى الطلب الذي تم إنشاؤه تلقائيًا <pk:O_RESULT-VARCHAR2-OUT/>. والحقيقة هي أن هناك خطأ في Oracle 12c: لا تتم إضافة متغيرات OUT إلى WSDL لـ Oracle WS الأصلي).



تظهر نتيجة المكالمة في جدول السجل.



الموجودات


يمكن استخدام تقنية Oracle XML DB Web Services الأصلية كحل صناعي شريطة عدم وجود حمل ثقيل على خدمة الويب هذه (طلب واحد في بضع ثوان). هذا الخيار مناسب عندما لا يكون لدى المستهلكين متطلبات صارمة لخدمة ويب (سماتها ، هياكل البيانات ، منطق المعالجة) ولا يوجد عقد محدد مسبقًا صارم. إذا كنت بحاجة إلى إنشاء خدمة ويب وفقًا لـ WSDL المحددة مسبقًا (كما هو الحال مع معداتنا الجديدة) ، فإن تقنية Native Oracle WS غير مناسبة.

خدمة بيانات Oracle REST


بدءًا من الإصدار 11.1 ، قدمت Oracle دعم RESTful الكامل في شكل وحدة منفصلة تسمى Oracle REST Data Service (ORDS).

ORDS هو تطبيق Java يسمح لك بإنشاء RESTful API لقاعدة بيانات Oracle باستخدام SQL و PL / SQL. وهو بديل لاستخدام Oracle HTTP Server و mod_plsql. في الأساس ، ORDS عبارة عن واجهة HTTP بين العالم الخارجي وقاعدة بيانات Oracle. تتيح لك هذه الواجهة إغلاق طلبات HTTP الواردة إلى أي كائن قاعدة بيانات - جدول أو إجراء PL / SQL.

كل ما يلزم القيام به هو تثبيت وتكوين وتشغيل ORDS لقاعدة البيانات المطلوبة. تأتي العملية الإضافية لإنشاء خدمات REST لكتابة التعليمات البرمجية في PL / SQL (أو حتى من خلال النقر في IDE إذا كانت التعليمات البرمجية كسولة جدًا في الكتابة).

لا يلزم تراخيص إضافية لتثبيت ORDS.

المتطلبات:

  • Java JDK 8 أو أعلى ؛
  • Oracle 11.1 أو أحدث (Oracle 11 XE الإصدار 2 مدعوم أيضًا).

يتم دعم العديد من خيارات نشر ORDS:

  • وضع مستقل؛
  • على خادم التطبيق (Oracle WebLogic Server و Apache Tomcat).

قدرات


تتيح لك ORDS:

  • تنظيم الوصول إلى الموارد بأسلوب RESTful.
  • بناء تفاعل بأسلوب "استدعاء الإجراء عن بعد" (التفاعل على غرار RPC).

ببساطة ، بمساعدة ORDS ، يمكنك فتح الوصول عبر HTTP إلى بعض كائنات قاعدة البيانات - الجداول والإجراءات والوظائف والحزم.

في الحالة الأولى ، نحن نتعامل مع الموارد بمعنى أنها مفهومة في النمط المعماري RESTful. يتم تعريف كل مورد بواسطة معرف موارد منتظم (URI) فريد ، ويتم تحديد العمليات ذات الموارد (CRUD - الإنشاء والقراءة والتعديل والحذف) من خلال العمليات من طلب HTTP: PUT و POST و GET و DELETE. على سبيل المثال ، إذا كان المورد عبارة عن إدخال في جدول الموظفين ، فسيكون هذا الإدخال متاحًا بواسطة معرف موارد منتظم (URI) للنموذج:

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

هنا ، يشار إلى اسم مخطط قاعدة البيانات واسم الجدول ومعرف السجل في الجدول في URI. وبالتالي ، فإن طلب HTTP هذا يقوم فعليًا بعملية SELECT من الجدول المحدد. مع العمليات الأخرى (الإضافة ، التغيير ، الحذف) ، يكون مبدأ الاتصال هو نفسه: يتم الإشارة إلى المسار إلى المورد في URI ، ويتم الإشارة إلى معلمات إضافية في نص الطلب ، على سبيل المثال ، قيم الحقول لإدراج السجل في الجدول.

في الحالة الثانية ، بدلاً من الوصول إلى المورد ، يتم استخدام استدعاء الإجراء مباشرة ، والذي يمكن أن يفعل كل شيء كما هو الحال في الحالة الأولى (CRUD) ، بالإضافة إلى تنفيذ أي منطق آخر ينفذ عملية الأعمال الضرورية. يمكن إجراء استدعاء إجراء من حزمة باستخدام طلب HTTP لهذا التنسيق:

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

يتم نقل معلمات الإجراء في نص الطلب في شكل هياكل تنسيق JSON {"param" : "value"}. يتم استخدام نفس النهج عند استخدام Oracle WS الأصلي ، الذي تمت مناقشته أعلاه ، ولكن في حالة خدمات REST لا توجد قيود مفروضة بواسطة بروتوكول SOAP.

الايجابيات

  • آلية مرنة تسمح لك بتنفيذ خدمات الويب بأي تعقيد.
  • بساطة التنفيذ: لتحويل إجراء PL / SQL إلى خدمة ويب ، تحتاج إلى تنفيذ بعض الأوامر النموذجية فقط. وباستخدام SQL Developer ، يتحول إنشاء واجهة برمجة تطبيقات REST إلى نقرة بالماوس بحد أدنى من كتابة التعليمات البرمجية.
  • القدرة على تنفيذ خدمة ويب بدون مصادقة.

ناقص

  • ORDS غير مضمّن في حزمة Oracle القياسية - يجب تثبيته بشكل منفصل لكل خادم (لا يلزم وجود تراخيص إضافية ، كما سبق ذكره). يمكن أن يكون هذا مشكلة إذا كان لديك الآلاف من خوادم قواعد البيانات.

التخصيص


يمكن تشغيل ORDS في وضعين: من خلال خادم التطبيق أو في الوضع المستقل.

تتناول هذه المقالة فقط خيار التشغيل في الوضع المستقل.

لكي تعمل ORDS تحتاج:

  1. تكوين الإعدادات قبل التثبيت.
  2. أكمل تثبيت ODRS.
  3. قم بتشغيل ORDS.
  4. تكوين ACL (لمخطط قاعدة البيانات المطلوبة).

الإعدادات


يحتوي توزيع ORDS على ملف به معلمات تبدو كالتالي:

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

يمكن العثور على وصف للمعلمات في معلمات التوثيق

للوضع المستقل:
معاملوصف
db.hostnameاسم أو عنوان IP لخادم قاعدة بيانات أوراكل
db.portمنفذ DB (مثل 1521)
db.servicenameقاعدة بيانات Servicename
db.usernameاسم مستخدم بوابة PL / SQL. الافتراضي = APEX_PUBLIC_USER ، لكن المثال لا يخطط لاستخدام APEX ، لذا يمكنك ترك هذه المعلمة فارغة
db.passwordكلمة مرور المستخدم (أيضًا لا تملأ)
migrate.apex.restانتقال خدمات RESTful APEX إلى ORDS. تعيين على خطأ إذا لم يتم استخدام APEX.
rest.services.apex.addتكوين ORDS للاستخدام في APEX
rest.services.ords.addقم بتعيين مخطط قاعدة البيانات لـ ORDS (ORDS_PUBLIC_USER و ORDS_METADATA). يجب أن تكون القيمة صحيحة
schema.tablespace.defaultمساحة الجدول الافتراضية لمخطط ORDS_METADATA
schema.tablespace.tempمساحة جدول مؤقتة لمخطط ORDS_METADATA
standalone.http.portالمنفذ الذي سيتم تشغيل ORDS عليه. سيتم استخدام هذا المنفذ في URI للوصول إلى WS.
user.tablespace.defaultمساحة الجدول الافتراضية لمخطط ORDS_PUBLIC_USER
user.tablespace.tempمساحة جدول مؤقتة لمخطط ORDS_PUBLIC_USER
ونتيجة لذلك ، يجب أن تبدو محتويات الملف كما يلي:

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

اكتمال الإعدادات اللازمة ، يمكنك متابعة التثبيت.

التركيب


نقوم بتنفيذ الأمر في نظام التشغيل:

java -jar ords.war

بشكل افتراضي ، يتم أخذ ملف التكوين من الدليل paramsالموجود بجوار ords.war. يمكنك تحديد المسار إلى هذا الملف بشكل صريح باستخدام المعلمة --parameterFile:

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

في مربع حوار التثبيت ، قم بما يلي:

  1. نشير إلى المسار إلى الدليل لحفظ التكوين (في المثال المشار إليه conf - ونتيجة لذلك ، في نفس الدليل حيث يوجد الملف ords.war، سيتم إنشاء دليل يتم فيه إنشاء confالملفات التي تحتوي على تكوين ORDS).
  2. بعد ظهور الأمر أدخل كلمة مرور قاعدة البيانات الخاصة بـ ORDS_PUBLIC_USER ، نقوم بإدخال كلمة المرور للمخطط ORDS_PUBLIC_USER. تحت هذا المستخدم ، سوف تتصل ORDS بقاعدة البيانات.
  3. بعد ظهور المطالبة أدخل 1 إذا كنت ترغب في استخدام PL / SQL Gateway أو 2 لتخطي هذه الخطوة ، فإننا نجيب على "2" ، لأننا لن نستخدم APEX ولا نحتاج إلى الترحيل من mod_plsql.
  4. بعد التعليمات أدخل 1 إذا كنت ترغب في البدء في الوضع المستقل أو يظهر 2 للخروج [1] ، نجيب "1".
  5. بعد التعليمات أدخل 1 إذا كنت تستخدم HTTP أو 2 إذا ظهر استخدام HTTPS [1] ، فإننا نجيب 1.

مربع حوار التثبيت
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)

ونتيجة لذلك ، سيتم إنشاء دليل بتكوين ORDS ، وستظهر مخططات الأداة المساعدة لـ ORDS في قاعدة البيانات.

نرى أيضًا: قم بتثبيت Oracle REST Data Services 3.0.X في أقل من 5 دقائق .

إطلاق


يبدأ الأمر في الوضع المستقل بواسطة الأمر:

java -jar ords.war standalone

مربع حوار التشغيل
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

بعد ذلك ، يتم تشغيل ORDS. سيكون عنوان خدمة الويب http: // <hostname>: / ords / ... ، حيث <hostname> هو اسم الكمبيوتر الذي يقوم بتشغيل ORDS (لا يجب أن يتطابق مع اسم خادم قاعدة البيانات ، أي أنه يمكن تشغيل ORDS على مضيف آخر ) ، <port> - المنفذ المحدد في تكوين ORDS.

إذا كنت ترغب في ذلك ، يمكنك إنشاء برنامج نصي لتشغيل ORDS تلقائيًا عند بدء تشغيل نظام التشغيل.

إعداد الوصول


والخطوة الأخيرة هي تكوين ACL. الخطوات هي نفسها مثل استخدام Oracle WS الأصلي.

يجب إكمال هذه الخطوة بعد إنشاء مخطط قاعدة البيانات ، لذا ستوضح الأمثلة أدناه بشكل منفصل متى تحتاج إلى تنفيذ هذا التكوين. حتى الآن ، يمكننا أن نفترض أن جميع الخطوات الأولية قد اكتملت ، والمضي قدمًا في الأمثلة.

مثال 1: معالج لطلب POST


كمثال ، ضع في اعتبارك خيار تنفيذ التفاعل على غرار RPC ، أي أننا سنصنع طريقة خدمة ويب ، والتي سيكون معالجها إجراء دفعي.

في الواقع ، في هذا الإصدار تم تنفيذ العمل مع ORDS في مشروعنا لشبكة التوزيع ، والنتيجة تلبي توقعاتها. لقد اتضح طريقة سريعة وعالمية لإنشاء طرق جديدة لخدمات الويب لعمليات الأعمال المختلفة - من العمل مع المعدات إلى واجهة برمجة التطبيقات للمواقع.

كما ذكر أعلاه ، يتم تضمين دعم ORDS أيضًا في SQL Developer (قاعدة بيانات IDE التي طورتها Oracle). في مطور SQL ، يتوفر إنشاء خدمات الويب مباشرة من عناصر القائمة أو قائمة السياق.

في هذه المقالة ، يتم إجراء أمثلة باستخدام SQL Developer (الإصدار 18) ، ولكن يتم أيضًا تضمين كود PL / SQL الذي يتم تنفيذه في قاعدة البيانات نتيجة للإجراءات في IDE.

نسخة قاعدة البيانات التي أجريت عليها التجارب:

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

إنشاء مستخدم اختبار لـ WS


على سبيل المثال ، نحتاج مرة أخرى إلى مخطط جديد - قم بإنشائه:

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

إنشاء مخطط قاعدة بيانات


بعد إنشاء الرسم البياني ، من الضروري جعله متاحًا من خلال ORDS.

لهذا:

  1. في SQL Developer ، قم بإنشاء اتصال لـ WS_TEST.
  2. في قائمة الاتصالات ، اتصل بقائمة السياق للاتصال الجديد. اختر خدمات REST → تمكين خدمات REST ... :


  3. في مربع الحوار ، حدد المربع بجوار تمكين المخطط (هنا يمكنك أيضًا تغيير معلمة " الاسم المستعار للمخطط " إذا كنت تريد ws_testعرض نص آخر في URI بدلاً من اسم النظام ):


  4. بالضغط على "التالي" ، سوف نرى كود PL / SQL الذي سيتم تنفيذه في نهاية المطاف في قاعدة البيانات (والتي يمكنك كتابتها بنفسك دون استخدام IDE):



قائمة:

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

إنشاء وحدة ونموذج


بعد ذلك ، تحتاج إلى إنشاء وحدة نمطية ونموذج للمورد.

الوحدة النمطية هي وحدة هيكلية تسمح لك بتجميع العديد من قوالب الموارد ذات الصلة منطقيا.

القالب هو خدمة ويب معينة تخدم مجموعة محددة من الأساليب لمورد.

في المصدر :

وحدة الموارد: وحدة تنظيمية تُستخدم لتجميع قوالب الموارد ذات الصلة.

قالب الموارد: خدمة RESTful فردية قادرة على خدمة الطلبات لمجموعة معينة من معرفات الموارد (معرفات الموارد العالمية). يتم تعريف مجموعة URIs من خلال نمط URI لقالب المصدر.


على سبيل المثال ، بالنسبة لمتجر عبر الإنترنت ، يمكن استدعاء وحدة نمطيةshop - في هذه الوحدة ، سيتم دمج جميع واجهات برمجة تطبيقات المتجر. يمكن أن تكون القوالب موارد محددة ، على سبيل المثال ، طلب (قالب order) ، كتالوج منتج (قالب item) ، دفع (قالب payment) ، إلخ.

لإنشاء وحدة ونموذج ، تحتاج إلى تنفيذ الخطوات التالية:

  1. في شجرة الكائن ، افتح قسم REST Data Services ، واستدعي قائمة السياق في قسم الوحدات ، حدد وحدة نمطية جديدة ... :


  2. في مربع حوار إنشاء الوحدة ، حدد اسم الوحدة ( shop) ، البادئة URI (نحدد أيضًا shop - في المثال أدناه نرى على الفور قالب عنوان خدمة الويب) ، ضع داو أمام النشر ، انقر فوق "التالي>" :


  3. في مربع الحوار التالي ، حدد اسم القالب ، على سبيل المثال order، ثم انقر مرة أخرى على "التالي>" .

    في مربع الحوار الأخير ، نرى جميع المعلمات المدخلة للوحدة النمطية والقالب. في علامة التبويب SQL ، يمكنك رؤية رمز PL / SQL الذي سيتم تنفيذه في قاعدة البيانات عند النقر فوق إنهاء :



لإنشاء وحدة نمطية shop ، يمكنك إضافة المزيد من أنماط - كما في شجرة الكائن، قائمة السياق واختيار إضافة قالب ... .

قائمة رمز لإنشاء وحدة نمطية ونموذج
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;
/

إنشاء معالج طلب HTTP


الآن نحن بحاجة إلى إنشاء معالج طلب HTTP لخدمتنا.

أولاً ، نحتاج إلى إنشاء كائنات قاعدة بيانات تحتوي على منطق معالجة الطلب.

نحتاج إلى جدول للتسجيل وحزمة يكون فيها كود معالج.

قم بإنشاء جدول باستخدام برنامج نصي:
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;

إنشاء حزمة:
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;
/

الآن بالنسبة للقالب الذي تم إنشاؤه ، تحتاج إلى إضافة معالج. قم بإضافة معالج لأسلوب HTTP POST.

للقيام بذلك ، قم بتنفيذ الخطوات التالية:

  1. نستدعي قائمة السياق للقالب ، حدد إضافة معالج ثم حدد طريقة 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;

    إذا لزم الأمر ، يمكنك الحصول على رمز PL / SQL لإنشاء معالج. للقيام بذلك ، في قائمة السياق لوحدة ORDS ، حدد REST Definition ثم حدد مكان إخراج البرنامج النصي لإنشاء الوحدة ، على سبيل المثال ، إلى الحافظة:


الكود الناتج لإنشاء الوحدة
-- 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;


ملاحظة: إذا قمت بإجراء إجراء إنشاء الوحدة ORDS.DEFINE_MODULEمرة أخرى ، فسيتم حذف جميع قوالب هذه الوحدة تلقائيًا ، ولن يكون هناك تحذير حول هذا!

مثال الاتصال


هذا هو المكان الذي تكون فيه خدمة الويب لدينا جاهزة. يبقى للتحقق من عملها.

للتحقق ، نقوم بتنفيذ الطلب:

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

ردًا على ذلك ، نحصل على:

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

نتيجة تنفيذ الطريقة عبارة عن سجل به نص الطلب والاستجابة في جدول السجل:



كما ترى ، تمت معالجة طلب HTTP المرسل بنجاح بواسطة الإجراء من الحزمة.

معلمات الطلب


أعلاه ، لقد رأينا بالفعل نتيجة خدمة ويب بسيطة. الآن دعونا نعقد المهمة قليلاً عن طريق إضافة معلمات إضافية إلى الطلب.

هناك طريقتان لتمرير المعلمات:

عبر URL. يتم تعيين المعلمات في URL في النموذج القياسي:

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

عبر HEADER. يتم تعيين المعلمات في رأس الطلب كما p1: val1

في ORDS في معالج الطلب ، يتم تعريف المعلمات كمتغيرات ربط.

نضيف معلمتين إلى المثال السابق: prm1- معلمة في URI ، prm2- معلمة في رأس الطلب.

لمعالجة هذه المعايير، PK_ORDS_API.process_request:أضفنا الإجراء، إضافة المعلمات a_prm_uriو a_prm_hdr، الذي قيم المعلمات لدينا من طلب سيأتي.

طلب إجراء معالج بمعلمات جديدة
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;

داخل الإجراء ، نسجل ببساطة قيم المعلمات الجديدة في السجل.

إضافة معلمات جديدة إلى معالج طلب POST - في شكل متغيرات ربط :prm_uriو :prm_hdr.

معالج طلب طلب POST مع المعلمات الجديدة:

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;

في المعالج ، في علامة التبويب معلمات ، قم بتعريف المتغيرات:


في هذا النموذج ، يحتوي الحقل الأول ( الاسم ) على اسم المعلمة المتوقعة في الطلب ، الحقل الثاني ( معلمة ربط ) - اسم متغير الربط الذي سيتم تحديده في معالج هذا الطلب.

دعنا ننفذ الطلب بمعلمات جديدة:



النتيجة - تم حفظ المعلمات من الطلب في السجل:


يرجى ملاحظة أنه يمكن أيضًا استرداد المعلمات من URI من متغير CGI QUERY_STRING، أي للحصول على المعلمات ، ليس من الضروري بدء متغيرات الربط - يمكنك تحليلها في إجراء المعالج نفسه طلب.

متغيرات CGI


عند العمل باستخدام HTTP في Oracle ، من الممكن الحصول على قيم متغيرات البيئة التي تعكس سياق طلب HTTP. يمكنك الحصول على قيم المتغيرات باستخدام الإجراء OWA_UTIL.get_cgi_env.

قائمة متغيرات CGI المتوفرة في 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

راجع أيضًا: رؤوس HTTP (OWA_UTIL) ومتغيرات الربط الخاصة بـ ORDS

مثال 2: الوصول إلى جدول من خلال ORDS


في هذا المثال ، نعتبر تنظيم الوصول إلى كائن قاعدة بيانات (إلى جدول) من خلال ORDS.

كما في المثال السابق ، نجعل الوصول دون إذن. تعرف على كيفية جعل الوصول الآمن إلى الموارد في الوثائق .

لجعل كائن قاعدة بيانات يمكن الوصول إليه من خلال ORDS ، تحتاج إلى تنفيذ خطوة واحدة فقط - الأمر ORDS.ENABLE_OBJECT. بعد ذلك ، يمكن الوصول إلى الكائن عن طريق معرف موارد منتظم (URI) للنموذج:

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

قم بإنشاء نمط اختبار


على سبيل المثال ، سنقوم بإنشاء جدول "الطلبات".

البرنامج النصي لإنشاء الجدول:

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;

فتح الوصول إلى الجدول من خلال ORDS


  1. في SQL المطور استدعاء قائمة السياق للجدول المطلوبة، حدد تمكين خدمة بقية ... .



  2. في نافذة إعدادات الوصول ، حدد مربع الاختيار تمكين الكائن ، وقم بإلغاء تحديد خانة الاختيار التفويض المطلوب ، وانقر فوق "إنهاء" (أو "التالي" لرؤية رمز PL / SQL المستلم):



  3. بعد تنفيذ هذه الخطوات ، T_ORDERيصبح الجدول متاحًا من خلال HTTP ، وهو معرف الموارد المنتظم الأساسي للوصول إلى المورد:

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

    قائمة تضمين الجدول:

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


قم بإنشاء أو تحرير سجل


الوصول إلى الجدول مفتوح - نتحقق من كيفية إنشاء وتحرير السجلات في الجدول من خلال ORDS.

لإنشاء سجل ، نقوم بتنفيذ الطلب PUT.

في وثائق ORDS ، PUTيتم تحديد الوصف التالي في وصف الطريقة :

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

بمعنى ، KeyValuesيجب ملء الحقل (مفتاح السجل) حتى يتم إنشاء سجل جديد. يجب أن يسرد الاستعلام نفسه كافة الحقول في الجدول (ولكن يمكن حذف حقل المفتاح).

تحقيق
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"
}

ردًا على ذلك ، نحصل على جميع حقول السجل الذي تم إنشاؤه للتو:

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

ننظر إلى محتويات الجدول - ظهر سجلنا الجديد:



لتغيير السجل ، نسمي نفس طريقة PUT. قم بتغيير الملاحظة في ترتيبنا:

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

في الرد نحصل على نفس JSON مع معلمات السجل المعدل. في الجدول ، نرى أنه تم تحديث الملاحظة:



استرجاع السجلات من جدول


هناك ثلاثة أوضاع للاستعلام عن البيانات من جدول:

  1. طلب الصفحة:

    GET http://<HOST>:<PORT>/ords/<SchemaAlias>/<ObjectAlias>/?offset=<Offset>&limit=<Limit>
  2. طلب الشروط:

     GET http://<HOST>:<PORT>/ords/<SchemaAlias>/<ObjectAlias>/?q=<FilterClause>
  3. طلب المفتاح الأساسي:

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

للحصول على جميع السجلات ، يمكنك تشغيل الاستعلام دون تحديد أي معلمات:

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

إجابة
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/"
      }
   ]
}

كيفية جعل أوراكل لإضافة ترميز إلى رأس نوع المحتوى سؤال مفتوح.

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

إجابة
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/"
      }
   ]
}

حذف سجل


للحذف ، استخدم طريقة HTTP DELETE.

تحقيق:

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

الطلب بشكله الأصلي:

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

إجابة:

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

الموجودات


ORDS هي آلية مرنة ومتنوعة إلى حد ما للعمل مع خدمات الويب ، والتي تسمح لك بتنفيذ REST الكامل. من حيث الأداء ، فهو أعلى بكثير من Native Oracle WS مع تحليل XML الداخلي الثقيل. لتنفيذ نظام عالي التحميل ، هذا الأسلوب غير مناسب: في هذه الحالة ، هناك حاجة إلى مكدس تكنولوجي مختلف - خادم تطبيق منفصل ، وطلبات التوكيل ، واستخدام قواعد البيانات المجمعة ، وما إلى ذلك. ومع ذلك ، بالنسبة لتطبيق الأنظمة التي تحتوي على عدد صغير نسبيًا من طلبات HTTP (حتى 10-20 في الثانية) ، فإن ORDS هو النهج الأمثل في كل من الأداء والمرونة. ORDS أدنى من Oracle WS الأصلي فقط من حيث إنشاء مواصفات خدمة الويب: يوفر الأخير مواصفات كاملة (WSDL) يمكن منحها "كما هي" إلى مستهلكي الخدمة. لدى ORDS القدرة أيضًاإنشاء وصف ، ولكن بالنسبة للنهج الذي تم تناوله في هذه المقالة مع خدمة عالمية بالكامل (عندما يكون هناك إجراء معالجة مشترك لجميع الخدمات) ، يصبح الإنشاء التلقائي للمواصفات مستحيلاً. لن تنشئ Oracle سوى مواصفات عالية المستوى ، ويجب وصف الأجزاء (نماذج البيانات) يدويًا.

النهج البديلة


جافا سيرفلت


يشبه هذا الخيار لإنشاء خدمات الويب في طريقة التكوين Native Oracle WS الأصلي: فهو يتطلب أيضًا استخدام خادم HTTP المدمج في Oracle ، بالإضافة إلى إعدادات ACL (في الواقع ، جميع الطرق الأخرى). ولكن ، بخلاف Native Oracle WS ، يعمل هذا الخيار مع HTTP الخالص. تتم كتابة معالجات الطلبات في هذه الحالة بلغة جافا ، ولا تنظر إلا إلى نوع طلب HTTP ( PUT، GET، POSTوما إلى ذلك ، على الرغم من أنه يمكن القيام به ومعالج واحد لجميع الأنواع) ، ويظل منطق المعالجة تمامًا وفقًا لتقدير المطور. يمكنك نقل نص الطلب "كما هو" إلى منطق قاعدة البيانات ، وتفكيكه ومعالجته هناك ، يمكنك ترك جزء من المنطق على جانب معالج Java ، واستدعاء الإجراء المطلوب من قاعدة البيانات اعتمادًا على البيانات الواردة في الطلب.

هذا النهج في تطبيق خدمات الويب عالمي تمامًا ولا يتطلب أيضًا تثبيت أي مكونات إضافية. لم نتمكن من تطبيقها فقط بسبب المتطلبات الصارمة للخدمة: كنا بحاجة إلى خدمة ويب لا تتطلب المصادقة. عند تنفيذ هذا النهج ، مطلوب المصادقة ، ولا يمكن التحايل على هذا الشرط.

راجع وثائق Oracle للحصول على مزيد من التفاصيل حول هذه الطريقة .

واصف الوصول إلى قاعدة البيانات (PL / SQL Servlet)


هذا الخيار مشابه تمامًا للخيار السابق ، فقط الإجراء PL / SQL المخزن هو بمثابة معالج الطلب.

مثال URL - يشار إلى اسم الحزمة واسم الإجراء والمعلمات (طلب GET):

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

في حالة طلب POST ، يجب إدخال أسماء المعلمات مباشرة في نص الطلب من خلال علامة "=" ، وهي غير ملائمة إلى حد ما ، نظرًا لأن نوع محتوى الطلب (ContentType) في هذه الحالة يمكن أن يكون نصًا فقط. يمكنك نقل بنية xml أو json فقط في هذا النموذج:

p_proc_param_name=<xml_data>…</xml_data>

هذا الإصدار من خدمة الويب قابل للتطبيق فقط في الحالات التي نتعامل فيها مع الطلبات البسيطة للغاية - استدعاءات الإجراءات مع أنواع البيانات البسيطة. لن يعمل نقل أي بنية معقدة متعددة المستويات في هذا الخيار.

يتم وصف هذا النهج بالتفصيل على موقع ORACLE-BASE.

استنتاج


يعد إنشاء خدمة ويب في Oracle مهمة بسيطة إلى حد ما ولا تتطلب كتابة أي نوع من التعليمات البرمجية المعقدة للغاية. في الوقت نفسه ، يدخل مطورو Oracle في ترسانتهم آلية قوية إلى حد ما تسمح لك بدمج الأنظمة غير المتجانسة أو أجزاء من الأنظمة من خلال HTTP.

في هذه المقالة ، درسنا أربعة أساليب لإنشاء خدمات الويب.

Native Oracle WS هي تقنية قديمة لها مزاياها على الرغم من ذلك: WSDL الذي يتم إنشاؤه تلقائيًا ، التحليل التلقائي لـ XML ، لا حاجة إلى تثبيت برامج إضافية. العيب الرئيسي هو الأداء المنخفض والحد من أنواع البيانات المدعومة.

ORDS- في رأيي ، الطريقة المفضلة لإنشاء خدمات الويب. مرنة بما يكفي وتنوعا. من مضايقات هذه الطريقة ، يمكننا فقط تمييز أنها غير مضمنة في حزمة Oracle القياسية ، أي أنها تتطلب تثبيتًا منفصلاً.

Java Servlet هي طريقة عالمية تمامًا لا تتطلب تثبيت برامج إضافية. ومع ذلك ، يجب القيام بكل شيء يدويًا تمامًا ، حيث لا توجد إمكانية لإنشاء خدمات تلقائية.

PL / SQL Servlet هو النهج الأقل نجاحًا. من الإيجابيات ، يمكننا تمييز أنه في هذا الخيار نحصل على القدرة على استدعاء الإجراءات المخزنة عبر HTTP دون الحاجة إلى تثبيت برامج إضافية ، أو بدون كتابة كود إضافي بلغات أخرى: كل التعليمات البرمجية مكتوبة فقط في PL / SQL.

شكرا لكم جميعا على اهتمامكم! آمل أن تكون مادة المقالة مفيدة لأولئك الذين يرتبطون بطريقة أو بأخرى بمنتجات أوراكل والذين يشعرون بالحيرة من مشاكل التكامل داخل النظام وبينه.


All Articles