Layanan webbanyak digunakan untuk integrasi antar komponen dari satu sistem atau antara sistem yang berbeda. Popularitas layanan web sebagai cara untuk berintegrasi adalah karena keserbagunaannya, serta kemudahan implementasi dan debugging. Fleksibilitas terkait dengan transfer data menggunakan Internet dan protokol HTTP. Layanan web membuatnya relatif mudah untuk membangun integrasi antara komponen yang ditulis dalam berbagai bahasa yang berjalan pada berbagai sistem operasi dan platform. Kesederhanaan implementasi layanan web dicapai melalui alat dan komponen bawaan di banyak IDE yang memungkinkan Anda untuk dengan cepat mengembangkan layanan web (sisi penyedia) dan kode yang diperlukan untuk memanggil layanan di sisi klien (sisi klien). Layanan debugging disederhanakan dengan penggunaan format pertukaran data yang dapat dibaca manusia - XML ββdan JSON. Selain,Ada banyak utilitas untuk layanan debugging dan pengujian, termasuk memuat.Pada artikel ini, kami akan mempertimbangkan beberapa cara untuk membuat layanan web langsung dari Oracle DBMS, yaitu, tanpa menggunakan alat pihak ketiga.Latar Belakang
Mengingat: sistem bisnis informasi dari jaringan distribusi besar (sekitar seribu toko ritel), yang terdiri dari banyak komponen dan subsistem. Di dalam setiap toko ada server utama - database Oracle dengan logika bisnis utama. Node kas dikelola oleh perangkat lunak terpisah dari basis data lokal mereka. Perangkat lunak ini secara berkala mengumpulkan data dari server utama (melalui WS SOAP) dan memberikan kembali hasil penjualan (pertukaran file).Kemajuan tidak berhenti, dan peralatan baru muncul di toko-toko. Data dari peralatan ini secara berkala harus dikirim ke server utama toko (periode - setiap beberapa menit), integrasi harus melalui layanan web, pesan harus memiliki format tertentu, otentikasi tidak diperlukan. Kami melihat kontrak pertukaran data dan menemukan bahwa teknologi layanan web yang digunakan tidak akan memungkinkan pembangunan integrasi dengan peralatan tersebut. Dan pencarian solusi dimulai ...Akibatnya, beberapa opsi untuk mengimplementasikan layanan web yang diinginkan dipertimbangkan, hingga menulis komponen terpisah yang akan membuka jendela untuk database Oracle untuk dunia HTTP: di satu sisi, itu akan menyediakan layanan web, di sisi lain, itu akan berinteraksi dengan database melalui JDBC. Kesulitannya adalah bahwa komponen baru, pertama, harus dipasang di seribu toko, dan, kedua, tautan lain akan muncul yang harus disertai. Oleh karena itu, prioritas masih menjadi pilihan untuk mengimplementasikan layanan web dengan alat bawaan Oracle.Sebagai hasil dari pencarian, kami menemukan empat cara yang akan kami pertimbangkan dalam artikel ini:- Layanan Web Asli Oracle XML DB
- Layanan Data Oracle REST
- Java Servlet
- Deskriptor Akses Database (PL / SQL servlet)
Dua opsi pertama akan dipertimbangkan secara lebih rinci. Layanan Web Asli Oracle XML DB DB digunakan di sistem kami pada awalnya, yaitu, itu diwarisi, untuk berbicara. ORDS menjadi pengganti untuk teknologi yang sudah ketinggalan zaman ini (terlepas dari kenyataan bahwa saya masih harus bekerja keras dan menginstal ORDS di ribuan toko).Dua metode lain - Java Servlet dan PL / SQL Servlet - kami mempertimbangkan bersama dengan ORDS ketika mencari alternatif untuk Native Oracle WS, tetapi kami tidak menggunakannya dalam proyek. Karena itu, kami tidak akan mempertimbangkan pendekatan ini secara terperinci dan membatasi diri kami pada referensi singkat.Artikel ini akan menyajikan beberapa contoh praktis penerapan layanan web dengan instruksi yang akan membantu menciptakan layanan yang berfungsi.Layanan Web Asli Oracle XML DB
Kemampuan
Memungkinkan Anda untuk mengatur akses ke database Oracle melalui HTTP menggunakan WS SOAP (versi 1.1):- - : , HTTP-.
- - (WSDL), , -.
- -. , β , β .
- XML-. , , XML, - β Oracle . , WS- Oracle β , - .
- WSDL , , - . β WSDL, WSDL , .
- ( 50 ). , β , . , - β , , .
Perlu dicatat bahwa otentikasi diperlukan untuk semua permintaan ke layanan web (dari dokumentasi : Otentikasi Dasar: Oracle XML DB mendukung Otentikasi Dasar, di mana klien mengirim nama pengguna dan kata sandi dalam teks yang jelas di header Otorisasi). Di Oracle, Anda dapat mengonfigurasi akses anonim ke sumber daya server melalui HTTP - menggunakan konfigurasi Oracle XML DB Protocol Server , tetapi sebenarnya itu hanya berfungsi untuk permintaan GET, dan otentikasi diperlukan untuk permintaan POST. Karena Native Oracle WS hanya bekerja melalui permintaan POST, tidak ada cara untuk mengkonfigurasi akses anonim untuk teknologi ini.Kustomisasi
Untuk menggunakan Native Oracle WS, Anda perlu:- Konfigurasikan server HTTP bawaan di Oracle.
- Konfigurasikan akses di dalam database Oracle (buka port HTTP).
- Buat servlet.
- Konfigurasikan ACL (Daftar Akses).
Mengkonfigurasi server Oracle XML DB HTTP
Server HTTP seharusnya sudah berfungsi secara default, tetapi dalam beberapa kasus konfigurasi pendengar tambahan mungkin diperlukan - menambahkan blok berikut ke DESCRIPTION_LIST:(DESCRIPTION=
(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=8080))(Presentation=HTTP)(Session=RAW)
)
Setelah itu, Anda harus memulai ulang pendengar.Konfigurasikan Akses HTTP
- Memeriksa port saat ini untuk HTTP.
SELECT dbms_xdb.gethttpport() AS http_port FROM dual;
Nilai "0" berarti akses HTTP dinonaktifkan. - Pengaturan port.
BEGIN
dbms_xdb.setHttpPort(8080);
COMMIT;
END;
/
Membuat servlet untuk layanan web
Agar layanan web berfungsi, pendaftaran servlet diperlukan dalam konfigurasi basis data.Script untuk membuat servlet
DECLARE
l_servlet_name VARCHAR2(32) := 'orawsv';
BEGIN
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
Konfigurasikan Daftar Akses
Untuk mengakses Oracle melalui HTTP, Anda perlu menambahkan aturan dalam konfigurasi DBMS. Ini dilakukan dengan menggunakan utilitas DBMS bawaan.Untuk mengkonfigurasi ACL Anda perlu:- skrip mengedit konfigurasi basis data (di bawah);
- skema basis data untuk mana konfigurasi dilakukan.
Yaitu, skema database yang ACL sedang dikonfigurasi harus sudah dibuat. Dalam contoh di bawah ini, akan ada referensi ke bagian ini, di tempat-tempat di mana Anda perlu membuat skema database baru - bagi mereka Anda perlu mengkonfigurasi ACL.Dalam skema SYS, kami menjalankan skrip konfigurasi ACL:
DECLARE
l_ws_user VARCHAR2(32) := 'WS_SOAP_TEST';
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||'"';
BEGIN
dbms_network_acl_admin.drop_acl(acl => '/sys/acls/'||l_acl);
EXCEPTION
WHEN dbms_network_acl_admin.acl_not_found THEN
NULL;
END;
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);
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;
/
Perlu dicatat segera bahwa konfigurasi ACL diperlukan saat menggunakan tidak hanya Native Oracle WS, tetapi juga semua metode lain untuk membuat layanan web yang dibahas dalam artikel ini.Contoh Layanan Web Menggunakan Prosedur Batch
Kita akan butuh:- Skema basis data tempat objek untuk memproses permintaan layanan web akan ditemukan.
- Tabel untuk logging.
- Paket dengan prosedur / fungsi.
- Alat apa pun yang memungkinkan Anda mengirim permintaan web. Dalam hal ini, aplikasi SOAP UI digunakan , tetapi Anda dapat memilih alat lain, hingga baris perintah.
Fitur:- Parameter prosedur harus memiliki tipe objek sederhana atau objek. Jika tidak, prosedur tidak akan dianggap sebagai metode layanan web dan tidak akan dimasukkan dalam daftar metode layanan.
- Untuk menerapkan struktur input atau output data yang kompleks, Anda perlu menggunakan tipe objek (tipe batch tidak dapat digunakan).
Kami membuat objek basis data yang diperlukan:- Skema
WS_TEST
:
CREATE USER WS_SOAP_TEST IDENTIFIED BY ws_soap_test QUOTA 200M ON USERS;
GRANT CREATE SESSION, RESOURCE TO ws_soap_test;
Segera tambahkan skema baru ke ACL. Script di bagian sebelumnya. - Dalam skema baru, buat tabel untuk logging
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 '/ ';
- Paket dengan prosedur sederhana:
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;
/
Layanan web paling sederhana dibuat dan siap digunakan.Untuk mengakses layanan, Anda perlu menggunakan URL dalam format berikut:http://[server]:[port]/[servlet_name]/[DB_SCHEMA]/[WS_OBJ]?wsdl
Di mana:[server] - nama domain atau alamat IP dari server database Oracle[port] - port untuk akses melalui HTTP yang ditentukan di bagian "Mengonfigurasi akses melalui HTTP"[servlet_name] - nama servlet yang ditentukan di bagian "Membuat servlet untuk web service β[DB_SCHEMA] - nama skema database (dalam huruf besar)[WS_OBJ] - nama layanan (dalam huruf besar), yang sama dengan nama objek database, dalam kasus kami - nama paketHarap perhatikan bahwa URL sensitif terhadap huruf besar-kecil!Contoh tautan:http://my.server:8080/orawsv/WS_SOAP_TEST/PK_NATIVE_WS_TEST?wsdl
Jika kita mengklik tautan ini di browser, kita akan dibuat secara otomatis berdasarkan paket WSDL kita: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>
Untuk menguji layanan, buat proyek SOAP baru di UI SOAP. Sebagai URL, tentukan alamat dari contoh di atas.Saat dibuka, Request 1
kita melihat bahwa templat permintaan sudah dibuat secara otomatis oleh WSDL yang ditentukan.Segera tambahkan otorisasi Dasar untuk permintaan - login dan kata sandi sama dengan saat menghubungkan ke database.
Contoh permintaan dan respons. Harap perhatikan bahwa baris telah ditambahkan ke permintaan yang dibuat secara otomatis <pk:O_RESULT-VARCHAR2-OUT/>
. Faktanya adalah bahwa ada bug di Oracle 12c: variabel OUT tidak ditambahkan ke WSDL untuk Native Oracle WS).
Hasil panggilan terlihat di tabel log.
temuan
Teknologi Asli Oracle XML DB Web Services dapat digunakan sebagai solusi industri asalkan tidak ada beban berat pada layanan web ini (satu permintaan dalam beberapa detik). Opsi ini cocok ketika konsumen tidak memiliki persyaratan ketat untuk layanan web (atributnya, struktur data, logika pemrosesan) dan tidak ada kontrak yang telah ditentukan sebelumnya. Jika Anda perlu membuat layanan web sesuai dengan WSDL yang telah ditentukan sebelumnya (seperti dalam kasus kami dengan peralatan baru), maka teknologi Native Oracle WS tidak akan sesuai.Layanan Data Oracle REST
Dimulai dengan versi 11.1, Oracle memperkenalkan dukungan penuh RESTful dalam bentuk modul terpisah yang disebut Oracle REST Data Service (ORDS).ORDS adalah aplikasi Java yang memungkinkan Anda membuat RESTful API untuk database Oracle menggunakan SQL dan PL / SQL. Ini adalah alternatif untuk menggunakan Oracle HTTP Server dan mod_plsql. Intinya, ORDS adalah antarmuka HTTP antara dunia luar dan basis data Oracle. Antarmuka ini memungkinkan Anda untuk menutup permintaan HTTP yang masuk ke objek basis data apa pun - tabel atau prosedur PL / SQL.Semua yang perlu dilakukan adalah menginstal, mengkonfigurasi dan menjalankan ORDS untuk database yang diperlukan. Proses lebih lanjut untuk membuat layanan REST dimulai dengan menulis kode dalam PL / SQL (atau bahkan dengan mengklik pada IDE jika kode tersebut terlalu malas untuk ditulis).Tidak diperlukan lisensi tambahan untuk menginstal ORDS.Persyaratan:- Java JDK 8 atau lebih tinggi;
- Oracle 11.1 atau lebih baru (Oracle 11 XE Release 2 juga didukung).
Beberapa opsi penyebaran ORDS didukung:- mode mandiri;
- pada server aplikasi (Oracle WebLogic Server, Apache Tomcat).
Kemampuan
ORDS memungkinkan Anda untuk:- Atur akses ke sumber daya dengan gaya yang tenang.
- Bangun interaksi dengan gaya "Panggilan Prosedur Jarak Jauh" (interaksi gaya RPC).
Sederhananya, menggunakan ORDS, Anda dapat membuka akses melalui HTTP ke objek database tertentu - tabel, prosedur, fungsi, paket.Dalam kasus pertama, kita berurusan dengan sumber daya dalam arti bahwa mereka dipahami dalam gaya arsitektur yang tenang. Setiap sumber daya ditentukan oleh URI unik, dan operasi dengan sumber daya (CRUD - buat, baca, modifikasi, hapus) ditentukan oleh operasi dari permintaan HTTP: PUT, POST, DAPATKAN, HAPUSKAN HAPUS. Misalnya, jika sumber daya adalah entri dalam tabel karyawan, maka entri ini akan tersedia oleh URI dari formulir:GET https://server:port/ords/workspace/hr/employees/7369
Di sini, nama skema database, nama tabel, dan ID rekaman dalam tabel ditunjukkan dalam URI. Dengan demikian, permintaan HTTP ini benar-benar melakukan operasi SELECT dari tabel yang ditentukan. Dengan operasi lain (menambah, mengubah, menghapus), prinsip komunikasi adalah sama: jalur ke sumber daya ditunjukkan dalam URI, dan parameter tambahan ditunjukkan di badan permintaan, misalnya, nilai bidang untuk memasukkan catatan ke dalam tabel.Dalam kasus kedua, alih-alih mengakses sumber daya, panggilan prosedur langsung digunakan, yang dapat melakukan semuanya sama seperti dalam kasus pertama (CRUD), serta menjalankan logika lain yang mengimplementasikan proses bisnis yang diperlukan. Panggilan prosedur dari suatu paket dapat dilakukan menggunakan permintaan HTTP format ini:http://localhost:8080/ords/my_schema/my_pkg/MY_PROC
Parameter untuk prosedur ditransfer dalam tubuh permintaan dalam bentuk struktur format JSON {"param" : "value"}
. Pendekatan yang sama digunakan ketika menggunakan Native Oracle WS, dibahas di atas, tetapi dalam kasus layanan REST tidak ada batasan yang diberlakukan oleh protokol SOAP.pro- Mekanisme fleksibel yang memungkinkan Anda untuk mengimplementasikan layanan web dengan kompleksitas apa pun.
- Kesederhanaan implementasi: untuk mengubah prosedur PL / SQL menjadi layanan web, Anda hanya perlu menjalankan beberapa perintah biasa. Dan menggunakan SQL Developer, membuat API REST berubah menjadi klik mouse dengan minimum penulisan kode.
- Kemampuan untuk mengimplementasikan layanan web tanpa otentikasi.
Minus- ORDS tidak termasuk dalam paket Oracle standar - itu harus diinstal secara terpisah untuk setiap server (lisensi tambahan, sebagaimana telah disebutkan, tidak diperlukan). Ini bisa menjadi masalah jika Anda memiliki ribuan server database.
Kustomisasi
ORDS dapat diluncurkan dalam dua mode: melalui server aplikasi atau dalam mode mandiri.Artikel ini hanya membahas opsi untuk berjalan dalam mode mandiri.Agar ORDS berfungsi, Anda perlu:- Konfigurasikan pengaturan sebelum instalasi.
- Selesaikan penginstalan ODRS.
- Luncurkan ORDS.
- Konfigurasikan ACL (untuk skema database yang diinginkan).
Pengaturan
Distribusi ORDS memiliki file dengan parameter yang terlihat seperti ini secara default: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
Deskripsi parameter dapat ditemukan dalam Parameter dokumentasiuntuk mode mandiri:Akibatnya, konten file akan terlihat seperti ini: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
Pengaturan yang diperlukan selesai, Anda dapat melanjutkan dengan instalasi.Instalasi
Kami menjalankan perintah di OS:java -jar ords.war
Secara default, file konfigurasi diambil dari direktori yang params
terletak di sebelah ords.war
. Anda dapat secara eksplisit menentukan jalur ke file ini menggunakan parameter --parameterFile
:java -jar ords.war --parameterFile /path/to/params/myown_params.properties
Dalam dialog instalasi, lakukan hal berikut:- Kami menunjukkan jalur ke direktori untuk menyimpan konfigurasi (dalam contoh itu ditunjukkan
conf
- sebagai hasilnya, di direktori yang sama di mana file tersebut berada ords.war
, direktori akan dibuat conf
di mana file dengan konfigurasi ORDS akan dibuat). - Setelah perintah Masukkan kata sandi basis data untuk ORDS_PUBLIC_USER muncul, kami memasukkan kata sandi untuk skema
ORDS_PUBLIC_USER
. Di bawah pengguna ini, ORDS akan terhubung ke database. - Setelah prompt Masukkan 1 jika Anda ingin menggunakan PL / SQL Gateway atau 2 untuk melewati langkah ini, kami menjawab "2", karena kami tidak akan menggunakan APEX dan kami tidak perlu bermigrasi
mod_plsql
. - Setelah instruksi Masukkan 1 jika Anda ingin memulai dalam mode mandiri atau 2 untuk keluar [1] muncul, kami menjawab "1".
- Setelah instruksi Masukkan 1 jika menggunakan HTTP atau 2 jika menggunakan HTTPS [1] muncul, kami menjawab 1.
Dialog instalasiD:\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)
Akibatnya, direktori dengan konfigurasi ORDS akan dibuat, dan skema utilitas untuk ORDS akan muncul dalam database.Lihat juga: Instal Oracle REST Data Services 3.0.X dalam waktu kurang dari 5 menit .Meluncurkan
Memulai dalam mode mandiri dilakukan dengan perintah:java -jar ords.war standalone
Luncurkan dialogD:\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
Setelah itu, ORDS aktif dan berjalan. Alamat layanan web akan menjadi http: // <hostname>: / ords / ..., di mana <hostname> adalah nama komputer yang menjalankan ORDS (tidak harus cocok dengan nama server database, yaitu, ORDS dapat dijalankan di host lain ), <port> - port yang ditentukan dalam konfigurasi ORDS.Jika mau, Anda dapat membuat skrip untuk menjalankan ORDS secara otomatis saat OS dimulai.Pengaturan akses
Dan langkah terakhir adalah mengkonfigurasi ACL. Langkah-langkahnya sama dengan menggunakan Native Oracle WS.Anda harus menyelesaikan langkah ini setelah skema database dibuat, jadi contoh di bawah ini akan menunjukkan secara terpisah kapan Anda perlu melakukan konfigurasi ini. Sejauh ini, kita dapat mengasumsikan bahwa semua langkah awal telah selesai, dan melanjutkan dengan contoh-contoh.Contoh 1: Handler untuk permintaan POST
Sebagai contoh, pertimbangkan opsi implementasi interaksi gaya RPC, yaitu, kami akan membuat metode layanan web, yang penangannya akan menjadi prosedur batch.Sebenarnya, dalam versi ini pekerjaan dengan ORDS diimplementasikan dalam proyek kami untuk jaringan distribusi, dan hasilnya memenuhi harapannya. Ternyata cara cepat dan universal untuk membuat metode baru layanan web untuk proses bisnis yang berbeda - dari bekerja dengan peralatan hingga API untuk situs.Seperti disebutkan di atas, dukungan ORDS juga termasuk dalam Pengembang SQL (IDE basis data yang dikembangkan oleh Oracle). Di SQL Developer, membuat layanan web tersedia langsung dari item menu atau menu konteks.Dalam artikel ini, contoh dibuat menggunakan SQL Developer (versi 18), tetapi kode PL / SQL yang dijalankan dalam database sebagai hasil dari tindakan dalam IDE juga disertakan.Versi database tempat eksperimen dilakukan: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
Membuat pengguna uji untuk WS
Sebagai contoh, kita perlu lagi skema baru - buat itu:CREATE USER WS_TEST IDENTIFIED BY ws_test QUOTA 200M ON USERS;
GRANT CREATE SESSION, RESOURCE TO ws_test;
Menyiapkan skema database
Setelah diagram dibuat, perlu untuk membuatnya dapat diakses melalui ORDS.Untuk ini:- Di SQL Developer, buat koneksi untuk
WS_TEST
. - Dalam daftar koneksi, panggil menu konteks untuk koneksi baru. Pilih Layanan REST β Aktifkan Layanan REST ... :

- Dalam dialog, centang kotak di sebelah Aktifkan skema (Anda juga dapat mengubah parameter " Skema alias " di sini jika Anda ingin
ws_test
teks lain ditampilkan di URI alih-alih nama skema ):

- Dengan mengklik "Next" , kita akan melihat kode PL / SQL yang pada akhirnya akan dieksekusi dalam database (dan Anda dapat menulis sendiri tanpa menggunakan IDE):

Daftar: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;
/
Membuat modul dan templat
Selanjutnya, Anda perlu membuat modul dan templat untuk sumber daya.Modul adalah unit struktural yang memungkinkan Anda untuk mengelompokkan beberapa templat sumber daya yang terkait secara logis.Templat adalah layanan web spesifik yang menyajikan serangkaian metode spesifik untuk sumber daya.Di sumber :Modul
sumber daya: Unit organisasi yang digunakan untuk mengelompokkan templat sumber daya terkait. Templat sumber daya: Layanan RESTful individu yang dapat melayani permintaan untuk beberapa set URI (Pengidentifikasi Sumber Daya Universal). Himpunan URI didefinisikan oleh Pola URI dari Templat Sumber Daya.Misalnya, untuk toko online, modul dapat dipanggilshop
- dalam modul ini semua API toko akan digabungkan. Templat dapat berupa sumber daya tertentu, misalnya, pesanan (templat order
), katalog produk (templat item
), pembayaran (templat payment
), dll.Untuk membuat modul dan templat, Anda perlu melakukan langkah-langkah berikut:- Di pohon objek, buka bagian REST Data Services, panggil menu konteks di bagian Modul , pilih Modul baru ... :

- Dalam dialog pembuatan modul, tentukan nama modul (
shop
), awalan URI (kami juga tentukan shop
- dalam contoh di bawah ini kami akan segera melihat seperti apa templat alamat layanan web), letakkan daw di depan Publish , klik "Next>" :

- Dalam dialog berikutnya, tentukan nama templat, misalnya
order
, dan kembali klik "Next>" .
Dalam dialog terakhir, kita melihat semua parameter yang dimasukkan dari modul dan template. Pada tab SQL , Anda bisa melihat kode PL / SQL yang akan dieksekusi di database ketika Anda mengklik Selesai :

Untuk membuat modul shop
, Anda dapat menambahkan lebih banyak pola - juga di pohon objek, menu konteks dan memilih Tambah Template ... .Daftar kode untuk membuat modul dan templateBEGIN
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;
/
Membuat Handler Permintaan HTTP
Sekarang kita perlu membuat penangan permintaan HTTP untuk layanan kami.Pertama, kita perlu membuat objek database yang akan berisi logika pemrosesan permintaan.Kami membutuhkan tabel untuk logging dan paket di mana akan ada kode handler.Buat tabel menggunakan skrip: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;
Buat 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;
/
Sekarang untuk templat yang dibuat Anda perlu menambahkan penangan. Tambahkan pawang untuk metode HTTP POST
.Untuk melakukan ini, lakukan langkah-langkah berikut:- Kami memanggil menu konteks untuk templat, pilih Tambah Handler dan kemudian pilih metode HTTP:

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

- 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;
Jika perlu, Anda bisa mendapatkan kode PL / SQL untuk membuat penangan. Untuk melakukan ini, di menu konteks modul ORDS, pilih REST Definition dan kemudian tentukan di mana akan menampilkan skrip pembuatan modul, misalnya, ke clipboard:

Kode yang dihasilkan untuk membuat modul
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;
Catatan: jika Anda melakukan prosedur pembuatan modul ORDS.DEFINE_MODULE
lagi, maka semua templat dari modul ini akan dihapus secara otomatis, dan tidak akan ada peringatan tentang ini!Contoh panggilan
Di sinilah layanan web kami siap. Masih memeriksa pekerjaannya.Untuk memeriksa, kami menjalankan permintaan: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" }
Sebagai tanggapan, kami mendapatkan:HTTP/1.1 200 OK
Date: Wed, 23 Oct 2019 16:54:53 GMT
Content-Type: application/json
Transfer-Encoding: chunked
{ "result" : "success" }
Hasil dari eksekusi metode adalah catatan dengan isi permintaan dan respons dalam tabel log:
Seperti yang Anda lihat, permintaan HTTP yang dikirim berhasil diproses oleh prosedur dari paket.Parameter dari permintaan
Di atas, kita telah melihat hasil dari layanan web sederhana. Sekarang mari kita sedikit mempersulit tugas dengan menambahkan parameter tambahan ke permintaan.Ada dua cara untuk melewati parameter:Via URL. Parameter diatur dalam URL dalam bentuk standar:http://...URI...?p1=val1&p2=val2
Melalui HEADER. Parameter ditetapkan di header permintaan sebagai p1: val1
Dalam ORDS dalam penangan permintaan, parameter didefinisikan sebagai variabel terikat.Kami menambahkan dua parameter ke contoh sebelumnya: prm1
- parameter di URI, prm2
- parameter di header permintaan.Untuk memproses parameter-parameter ini, PK_ORDS_API.process_request:
kami menambahkan prosedur, menambahkan parameter a_prm_uri
dan a_prm_hdr
, ke mana nilai-nilai parameter kami dari permintaan akan datang.Minta prosedur penangan dengan parameter baruPROCEDURE 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;
Di dalam prosedur, kami cukup mencatat nilai-nilai parameter baru di log.Tambahkan parameter baru ke penangan permintaan POST - dalam bentuk variabel bind :prm_uri
dan :prm_hdr
.Penangan permintaan permintaan POST dengan parameter baru: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;
Dalam penangan, pada tab Parameter , deklarasikan variabel:
Dalam formulir ini, bidang pertama ( Nama ) berisi nama parameter yang diharapkan dalam permintaan, bidang kedua ( Parameter Bind ) - nama variabel terikat yang akan ditentukan dalam penangan permintaan ini.Mari kita jalankan permintaan dengan parameter baru:
Hasil - parameter dari permintaan disimpan dalam log:
Harap dicatat bahwa parameter dari URI juga dapat diambil dari variabel CGI QUERY_STRING
, yaitu, untuk mendapatkan parameter itu tidak perlu memulai variabel mengikat - Anda dapat menguraikannya dalam prosedur handler itu sendiri permintaan.Variabel CGI
Ketika bekerja dengan HTTP di Oracle, dimungkinkan untuk mendapatkan nilai-nilai variabel lingkungan yang mencerminkan konteks permintaan HTTP. Anda bisa mendapatkan nilai variabel menggunakan prosedur OWA_UTIL.get_cgi_env
.Daftar Variabel CGI Tersedia dalam PL / SQLAPEX_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
Lihat juga: Tajuk HTTP (OWA_UTIL) dan Variabel Pengikat Khusus-ORDSContoh 2: Mengakses tabel melalui ORDS
Dalam contoh ini, kami mempertimbangkan organisasi akses ke objek database (ke tabel) melalui ORDS.Seperti pada contoh sebelumnya, kami membuat akses tanpa otorisasi. Lihat cara membuat akses yang aman ke sumber daya dalam dokumentasi .Untuk membuat objek basis data dapat diakses melalui ORDS, Anda hanya perlu melakukan satu langkah - perintah ORDS.ENABLE_OBJECT
. Setelah itu, objek dapat diakses oleh URI berupa:http://<HOST>:<PORT>/ords/<SchemaAlias>/<ObjectAlias>
.Buat pola uji
Sebagai contoh, kita akan membuat tabel "Pesanan".Skrip pembuatan tabel: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;
Membuka akses meja melalui ORDS
- Dalam SQL Developer memanggil menu konteks untuk meja, pilih Aktifkan Layanan REST ... .

- Di jendela pengaturan akses, centang kotak Aktifkan objek , hapus centang pada kotak centang Otorisasi yang diperlukan , klik "Selesai" (atau "Berikutnya" untuk melihat kode PL / SQL yang diterima):

- Setelah melakukan langkah-langkah ini, tabel
T_ORDER
menjadi tersedia melalui HTTP, URI dasar untuk mengakses sumber daya:
http://<server>:<port>/ords/ws_test/t_order
Daftar inklusi tabel:
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;
/
Buat atau edit catatan
Akses ke tabel terbuka - kami memeriksa bagaimana Anda dapat membuat dan mengedit catatan dalam tabel melalui ORDS.Untuk membuat catatan, jalankan permintaan PUT
.Dalam dokumentasi ORDS, uraian berikut PUT
ditentukan dalam uraian metode :PUT http://<HOST>:<PORT>/ords/<SchemaAlias>/<ObjectAlias>/<KeyValues>
Artinya, bidang KeyValues
(kunci rekaman) harus diisi bahkan untuk catatan baru yang dibuat. Kueri itu sendiri harus mencantumkan semua bidang dalam tabel (tetapi bidang kunci bisa dihilangkan).PenyelidikanPUT 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"
}
Sebagai tanggapan, kami mendapatkan semua bidang catatan yang baru saja dibuat:
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/"
}
]
}
Kami melihat isi tabel - catatan baru kami muncul:
Untuk mengubah catatan, kami memanggil metode PUT yang sama. Ubah catatan dalam pesanan kami: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. "
}
Sebagai tanggapan kita mendapatkan JSON yang sama dengan parameter dari catatan yang dimodifikasi. Di tabel, kita melihat bahwa catatan telah diperbarui:
Mengambil catatan dari sebuah tabel
Ada tiga mode permintaan data dari tabel:- Permintaan halaman:
GET http://<HOST>:<PORT>/ords/<SchemaAlias>/<ObjectAlias>/?offset=<Offset>&limit=<Limit>
- Permintaan kondisi:
GET http://<HOST>:<PORT>/ords/<SchemaAlias>/<ObjectAlias>/?q=<FilterClause>
- Permintaan Kunci Utama:
GET http://<HOST>:<PORT>/ords/<SchemaAlias>/<ObjectAlias>/<KeyValues>
Untuk mendapatkan semua catatan, Anda dapat menjalankan kueri tanpa menentukan parameter apa pun:GET http://<server>:<port>/ords/ws_test/t_order/
MenjawabHTTP/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/"
}
]
}
Bagaimana membuat Oracle menambahkan encoding ke header Content-Type adalah pertanyaan terbuka.GET http://<server>:<port>/ords/ws_test/t_order/25
MenjawabHTTP/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/"
}
]
}
Hapus catatan
Untuk menghapus, gunakan metode HTTP DELETE
.Penyelidikan:DELETE http://<server>:<port>/ords/ws_test/t_order/?q={"id_order":25}
Permintaan dalam bentuk aslinya:DELETE http://<server>:<port>/ords/ws_test/t_order/?q=%7B%22id_order%22%3A25%7D
Menjawab:HTTP/1.1 200 OK
Date=Fri, 25 Oct 2019 16:23:39 GMT
Content-Type=application/json
Transfer-Encoding=chunked
{"rowsDeleted":1}
temuan
ORDS adalah mekanisme yang cukup fleksibel dan serbaguna untuk bekerja dengan layanan web, yang memungkinkan Anda untuk mengimplementasikan REST lengkap. Dalam hal kinerja, itu jauh lebih unggul dari Native Oracle WS dengan parsing XML internal yang berat. Untuk menerapkan sistem yang sangat dimuat, pendekatan ini tidak cocok: dalam hal ini, tumpukan teknologi yang berbeda diperlukan - server aplikasi yang terpisah, permintaan proxy, menggunakan database berkerumun, dan sebagainya. Namun, untuk implementasi sistem dengan jumlah permintaan HTTP yang relatif kecil (hingga 10-20 per detik), ORDS adalah pendekatan optimal dalam kinerja dan fleksibilitas. ORDS lebih rendah daripada Native Oracle WS hanya dalam hal menghasilkan spesifikasi layanan web: yang terakhir memberikan spesifikasi selesai sempurna (WSDL) yang dapat diberikan "sebagaimana adanya" kepada konsumen layanan. ORDS juga memiliki kemampuanmenghasilkan deskripsi, tetapi untuk pendekatan yang dipertimbangkan dalam artikel ini dengan layanan yang sepenuhnya universal (ketika ada prosedur pemrosesan umum untuk semua layanan), pembuatan spesifikasi otomatis menjadi mustahil. Oracle hanya akan menghasilkan spesifikasi tingkat atas, dan bagian-bagian (model data) harus dijelaskan secara manual.Pendekatan alternatif
Java Servlet
Opsi ini untuk membuat layanan web dalam metode konfigurasi mirip dengan Native Oracle WS: ini juga memerlukan penggunaan server HTTP bawaan Oracle, serta pengaturan ACL (seperti, memang, semua metode lain). Tapi, tidak seperti Native Oracle WS, opsi ini bekerja dengan HTTP murni. Permintaan penangan dalam kasus ini ditulis di Jawa dan melihat hanya pada jenis HTTP-request ( PUT
, GET
, POST
, dan sebagainya, meskipun hal itu dapat dilakukan dan satu handler untuk semua jenis), dan pengolahan logika benar-benar tetap pada kebijaksanaan pengembang. Anda dapat mentransfer tubuh permintaan "sebagaimana adanya" ke logika database, dan di sana dapat dibongkar dan diproses, Anda dapat meninggalkan bagian dari logika di sisi Java handler, dan dari database memanggil prosedur yang diperlukan tergantung pada data yang diterima dalam permintaan.Pendekatan untuk implementasi layanan web ini cukup universal dan juga tidak memerlukan pemasangan komponen tambahan apa pun. Kami tidak berhasil menerapkannya hanya karena persyaratan ketat untuk layanan: kami membutuhkan layanan web yang tidak memerlukan otentikasi. Saat menerapkan pendekatan ini, otentikasi diperlukan, dan persyaratan ini tidak dapat dielakkan.Lihat dokumentasi Oracle untuk detail lebih lanjut tentang metode ini .Deskriptor Akses Database (PL / SQL Servlet)
Opsi ini benar-benar mirip dengan yang sebelumnya, hanya prosedur tersimpan PL / SQL bertindak sebagai penangan permintaan.Contoh URL - nama paket, nama prosedur, parameter (permintaan GET) ditunjukkan:GET http://<server>:<port>/servlet_plsql/pi_test.test_serv?p_path=ppp
Dalam kasus permintaan POST, nama parameter harus dimasukkan secara langsung di badan permintaan melalui tanda β=β, yang agak tidak nyaman, karena jenis konten permintaan (ContentType) dalam kasus ini hanya dapat berupa teks. Anda dapat mentransfer struktur xml atau json hanya dalam bentuk ini:p_proc_param_name=<xml_data>β¦</xml_data>
Versi layanan web ini hanya berlaku jika kami menangani permintaan yang sangat sederhana - panggilan prosedur dengan tipe data sederhana. Mentransmisikan struktur multi-level yang kompleks dalam opsi ini tidak akan berfungsi.Pendekatan ini dijelaskan secara rinci di situs web ORACLE-BASE.Kesimpulan
Menciptakan layanan web di Oracle adalah tugas yang cukup sederhana yang tidak memerlukan penulisan segala jenis kode super kompleks. Pada saat yang sama, pengembang Oracle masuk ke gudang senjata mereka mekanisme yang cukup kuat yang memungkinkan Anda untuk mengintegrasikan sistem heterogen atau bagian dari sistem melalui HTTP.Dalam artikel ini, kami menguji empat pendekatan untuk menciptakan layanan web.Native Oracle WS adalah teknologi yang sudah ketinggalan zaman, yang memiliki kelebihan: WSDL yang dihasilkan secara otomatis, penguraian XML secara otomatis, tidak perlu menginstal perangkat lunak tambahan. Kelemahan utama adalah kinerja yang rendah dan keterbatasan tipe data yang didukung.ORDS- Menurut pendapat saya, cara yang disukai untuk membuat layanan web. Cukup fleksibel dan fleksibel. Dari ketidaknyamanan metode ini, kita hanya dapat membedakan bahwa itu tidak termasuk dalam paket Oracle standar, yaitu, memerlukan instalasi yang terpisah.Java Servlet adalah cara yang sepenuhnya universal yang tidak memerlukan instalasi perangkat lunak tambahan. Namun, semuanya perlu dilakukan sepenuhnya secara manual, karena tidak ada kemungkinan layanan penghasil otomatis.PL / SQL Servlet adalah pendekatan yang paling tidak berhasil. Dari kelebihannya, kita dapat membedakan bahwa dalam versi ini kita mendapatkan kemampuan untuk memanggil prosedur tersimpan melalui HTTP tanpa perlu menginstal perangkat lunak tambahan, atau tanpa menulis kode tambahan dalam bahasa lain: semua kode hanya ditulis dalam PL / SQL.Terima kasih atas perhatian Anda! Saya berharap materi artikel ini akan bermanfaat bagi mereka yang entah bagaimana terhubung dengan produk Oracle dan bingung dengan masalah integrasi intra-sistem dan intersistem.