Services Weblargement utilisĂ© pour l'intĂ©gration entre les composants d'un systĂšme ou entre diffĂ©rents systĂšmes. La popularitĂ© des services Web comme moyen d'intĂ©gration est due Ă leur polyvalence, ainsi qu'Ă leur facilitĂ© de mise en Ćuvre et de dĂ©bogage. La polyvalence est associĂ©e au transfert de donnĂ©es via Internet et le protocole HTTP. Les services Web facilitent relativement la crĂ©ation d'intĂ©grations entre des composants Ă©crits dans diffĂ©rents langages qui s'exĂ©cutent sur diffĂ©rents systĂšmes d'exploitation et plates-formes. La simplicitĂ© de la mise en Ćuvre des services Web est obtenue grĂące aux outils et composants intĂ©grĂ©s dans de nombreux IDE qui vous permettent de dĂ©velopper rapidement Ă la fois le service Web (cĂŽtĂ© fournisseur) et le code nĂ©cessaire pour appeler le service cĂŽtĂ© client (cĂŽtĂ© client). Les services de dĂ©bogage sont simplifiĂ©s par l'utilisation de formats d'Ă©change de donnĂ©es lisibles par l'homme - XML ââet JSON. Outre,Il existe de nombreux utilitaires pour les services de dĂ©bogage et de test, y compris la charge.Dans cet article, nous examinerons plusieurs façons de crĂ©er des services Web directement Ă partir d'Oracle DBMS, c'est-Ă -dire sans utiliser d'outils tiers.Contexte
ĂlĂ©ments fournis: systĂšme d'information commercial d'un grand rĂ©seau de distribution (environ un millier de magasins de dĂ©tail), composĂ© de nombreux composants et sous-systĂšmes. Ă l'intĂ©rieur de chaque magasin, il y a un serveur principal - une base de donnĂ©es Oracle avec la logique mĂ©tier principale. Les nĆuds de caisse sont gĂ©rĂ©s par un logiciel distinct de leur base de donnĂ©es locale. Ce logiciel collecte pĂ©riodiquement les donnĂ©es du serveur principal (via WS SOAP) et rend les rĂ©sultats de la vente (Ă©change de fichiers).Les progrĂšs ne se sont pas arrĂȘtĂ©s et de nouveaux Ă©quipements sont apparus dans les magasins. Les donnĂ©es de cet Ă©quipement doivent ĂȘtre pĂ©riodiquement envoyĂ©es au serveur principal de la boutique (pĂ©riode - toutes les quelques minutes), l'intĂ©gration doit nĂ©cessairement passer par le service Web, le message doit avoir un certain format, l'authentification n'est pas nĂ©cessaire. Nous avons examinĂ© les contrats d'Ă©change de donnĂ©es et dĂ©couvert que la technologie utilisĂ©e des services Web ne permettrait pas l'intĂ©gration du bĂątiment avec un tel Ă©quipement. Et la recherche d'une solution a commencĂ© ...En consĂ©quence, plusieurs options pour la mise en Ćuvre du service Web nĂ©cessaire ont Ă©tĂ© envisagĂ©es, jusqu'Ă l'Ă©criture d'un composant distinct qui ouvrirait une fenĂȘtre pour la base de donnĂ©es Oracle pour la base de donnĂ©es Oracle: d'une part, il fournirait un service Web, d'autre part, il interagirait avec la base de donnĂ©es via JDBC. La difficultĂ© est que le nouveau composant, d'une part, devrait ĂȘtre installĂ© dans un millier de magasins, et, d'autre part, un autre lien serait apparu qu'il faudrait accompagner. Par consĂ©quent, la prioritĂ© Ă©tait toujours l'option d'implĂ©menter un service Web avec les outils intĂ©grĂ©s d'Oracle.Ă la suite des recherches, nous avons trouvĂ© quatre façons que nous considĂ©rerons dans cet article:- Services Web Oracle XML DB natifs
- Service de données Oracle REST
- Servlet Java
- Descripteur d'accÚs à la base de données (servlet PL / SQL)
Les deux premiĂšres options seront examinĂ©es plus en dĂ©tail. Les services Web Oracle XML DB natifs Ă©taient initialement utilisĂ©s dans notre systĂšme, c'est-Ă -dire qu'ils Ă©taient hĂ©ritĂ©s, pour ainsi dire. ORDS est devenu un remplacement pour cette technologie obsolĂšte (malgrĂ© le fait que je devais encore travailler dur et installer ORDS dans un millier de magasins).Deux autres mĂ©thodes - Java Servlet et PL / SQL Servlet - nous avons considĂ©rĂ© avec ORDS lors de la recherche d'une alternative Ă Native Oracle WS, mais nous ne l'avons pas utilisĂ©e dans le projet. Par consĂ©quent, nous ne considĂ©rerons pas ces approches en dĂ©tail et nous limiterons Ă une brĂšve rĂ©fĂ©rence.L'article prĂ©sentera quelques exemples pratiques de mise en Ćuvre de services Web avec des instructions qui aideront Ă crĂ©er un service fonctionnel.Services Web Oracle XML DB natifs
Capacités
Vous permet d'organiser l'accÚs à la base de données Oracle via HTTP à l'aide de WS SOAP (version 1.1):- - : , HTTP-.
- - (WSDL), , -.
- -. , â , â .
- XML-. , , XML, - â Oracle . , WS- Oracle â , - .
- WSDL , , - . â WSDL, WSDL , .
- ( 50 ). , â , . , - â , , .
Il convient de noter que l'authentification est requise pour toutes les demandes au service Web (Ă partir de la documentation : Authentification de base: Oracle XML DB prend en charge l'authentification de base, oĂč un client envoie le nom d'utilisateur et le mot de passe en texte clair dans l'en-tĂȘte d'autorisation). Dans Oracle, vous pouvez configurer l'accĂšs anonyme aux ressources du serveur via HTTP - Ă l'aide de la configuration du serveur de protocole Oracle XML DB , mais en fait, cela ne fonctionne que pour les demandes GET, et l'authentification est requise pour les demandes POST. Ătant donnĂ© que Native Oracle WS ne fonctionne que par le biais de requĂȘtes POST, il n'y a aucun moyen de configurer l'accĂšs anonyme pour cette technologie.Personnalisation
Pour utiliser Native Oracle WS, vous aurez besoin de:- Configurez le serveur HTTP intégré dans Oracle.
- Configurez l'accÚs à l'intérieur de la base de données Oracle (ouvrez le port HTTP).
- Créez une servlet.
- Configurez ACL (Access List).
Configurer le serveur HTTP Oracle XML DB
Le serveur HTTP devrait dĂ©jĂ fonctionner par dĂ©faut, mais dans certains cas, une configuration d'Ă©coute supplĂ©mentaire peut ĂȘtre requise - en ajoutant le bloc suivant Ă DESCRIPTION_LIST:(DESCRIPTION=
(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=8080))(Presentation=HTTP)(Session=RAW)
)
AprÚs cela, vous devez redémarrer l'écouteur.Configurer l'accÚs HTTP
- Vérification du port actuel pour HTTP.
SELECT dbms_xdb.gethttpport() AS http_port FROM dual;
Une valeur de "0" signifie que l'accÚs HTTP est désactivé. - Configuration du port.
BEGIN
dbms_xdb.setHttpPort(8080);
COMMIT;
END;
/
Création d'une servlet pour un service Web
Pour que le service Web fonctionne, l'enregistrement du servlet est requis dans la configuration de la base de données.Script pour créer un servlet
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
Configurer la liste d'accĂšs
Pour accéder à Oracle via HTTP, vous devez ajouter des rÚgles dans la configuration du SGBD. Cela se fait à l'aide des utilitaires SGBD intégrés.Pour configurer l'ACL, vous aurez besoin de:- script d'édition de la configuration de la base de données (ci-dessous);
- schéma de base de données pour lequel la configuration est effectuée.
Autrement dit, le schĂ©ma de base de donnĂ©es pour lequel ACL est configurĂ© doit dĂ©jĂ ĂȘtre créé. Dans les exemples ci-dessous, il y aura des rĂ©fĂ©rences Ă cette section, aux endroits oĂč vous devez crĂ©er de nouveaux schĂ©mas de base de donnĂ©es - pour eux, vous devrez configurer l'ACL.Dans le schĂ©ma SYS, nous exĂ©cutons le script de configuration ACL:
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;
/
Il convient de noter tout de suite que la configuration ACL est requise lors de l'utilisation non seulement de Native Oracle WS, mais également de toutes les autres méthodes de création de services Web décrites dans cet article.Exemple de service Web à l'aide d'une procédure par lots
Nous aurons besoin:- Schéma de base de données dans lequel se trouveront les objets de traitement des demandes de service Web.
- Tableau de journalisation.
- Package avec procédure / fonction.
- Tout outil qui vous permet d'envoyer des demandes Web. Dans ce cas, l'application SOAP UI a été utilisée , mais vous pouvez choisir n'importe quel autre outil, jusqu'à la ligne de commande.
Fonctionnalités:- Les paramÚtres de procédure doivent avoir des types simples ou d'objet. Sinon, la procédure ne sera pas perçue comme une méthode de service Web et ne sera pas incluse dans la liste des méthodes de service.
- Pour implĂ©menter des structures complexes de donnĂ©es d'entrĂ©e ou de sortie, vous devez utiliser des types d'objets (les types de lots ne peuvent pas ĂȘtre utilisĂ©s).
Nous créons les objets de base de données nécessaires:- Schéma
WS_TEST
:
CREATE USER WS_SOAP_TEST IDENTIFIED BY ws_soap_test QUOTA 200M ON USERS;
GRANT CREATE SESSION, RESOURCE TO ws_soap_test;
Ajoutez immédiatement un nouveau schéma à l'ACL. Le script de la section précédente. - Dans le nouveau schéma, créez une table pour la journalisation
T_WS_REQ_LOG
:
CREATE TABLE T_WS_REQ_LOG
(
id_log NUMBER GENERATED ALWAYS AS IDENTITY,
message VARCHAR2(2000),
proc VARCHAR2(128),
dtm_request TIMESTAMP(6) DEFAULT SYSTIMESTAMP
);
COMMENT ON TABLE T_WS_REQ_LOG IS ' HTTP-';
COMMENT ON COLUMN T_WS_REQ_LOG.id_log IS '';
COMMENT ON COLUMN T_WS_REQ_LOG.message IS '';
COMMENT ON COLUMN T_WS_REQ_LOG.proc IS '';
COMMENT ON COLUMN T_WS_REQ_LOG.dtm_request IS '/ ';
- Package avec une procédure simple:
CREATE OR REPLACE PACKAGE PK_NATIVE_WS_TEST IS
PROCEDURE proc_simple
( a_id INTEGER
, a_data VARCHAR2
, o_result OUT VARCHAR2
);
END PK_NATIVE_WS_TEST;
/
CREATE OR REPLACE PACKAGE BODY PK_NATIVE_WS_TEST IS
PROCEDURE proc_simple
( a_id INTEGER
, a_data VARCHAR2
, o_result OUT VARCHAR2
)
AS
BEGIN
INSERT INTO t_ws_req_log (message, proc)
VALUES ('ID='||a_id||'; DATA='||a_data, 'proc_simple')
RETURNING id_log INTO o_result;
END proc_simple;
END PK_NATIVE_WS_TEST;
/
Le service Web le plus simple est créé et prĂȘt Ă l'emploi.Pour accĂ©der au service, vous devez utiliser l'URL au format suivant:http://[server]:[port]/[servlet_name]/[DB_SCHEMA]/[WS_OBJ]?wsdl
OĂč:[serveur] - nom de domaine ou adresse IP du serveur de base de donnĂ©es Oracle[port] - port d'accĂšs via HTTP spĂ©cifiĂ© dans la section "Configuration de l'accĂšs via HTTP"[nom_servlet] - nom du servlet spĂ©cifiĂ© dans la section "CrĂ©ation d'une servlet pour le Web service â[DB_SCHEMA] - nom du schĂ©ma de base de donnĂ©es (en majuscules)[WS_OBJ] - nom du service (en majuscules), qui est Ă©gal au nom de l'objet de base de donnĂ©es, dans notre cas - le nom du packageNotez que l'URL est importante!Exemple de lien:http://my.server:8080/orawsv/WS_SOAP_TEST/PK_NATIVE_WS_TEST?wsdl
Si nous cliquons sur ce lien dans le navigateur, nous serons automatiquement créés sur la base de notre package WSDL:Wsdl<definitions name="PK_NATIVE_WS_TEST"
targetNamespace="http://xmlns.oracle.com/orawsv/WS_SOAP_TEST/PK_NATIVE_WS_TEST"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="http://xmlns.oracle.com/orawsv/WS_SOAP_TEST/PK_NATIVE_WS_TEST"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
<types>
<xsd:schema targetNamespace="http://xmlns.oracle.com/orawsv/WS_SOAP_TEST/PK_NATIVE_WS_TEST"
elementFormDefault="qualified">
<xsd:element name="PROC_SIMPLEInput">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="A_DATA-VARCHAR2-IN" type="xsd:string"/>
<xsd:element name="A_ID-NUMBER-IN" type="xsd:integer"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="PROC_SIMPLEOutput">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="O_RESULT" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</types>
<message name="PROC_SIMPLEInputMessage">
<part name="parameters" element="tns:PROC_SIMPLEInput"/>
</message>
<message name="PROC_SIMPLEOutputMessage">
<part name="parameters" element="tns:PROC_SIMPLEOutput"/>
</message>
<portType name="PK_NATIVE_WS_TESTPortType">
<operation name="PROC_SIMPLE">
<input message="tns:PROC_SIMPLEInputMessage"/>
<output message="tns:PROC_SIMPLEOutputMessage"/>
</operation>
</portType>
<binding name="PK_NATIVE_WS_TESTBinding"
type="tns:PK_NATIVE_WS_TESTPortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="PROC_SIMPLE">
<soap:operation
soapAction="PROC_SIMPLE"/>
<input>
<soap:body parts="parameters" use="literal"/>
</input>
<output>
<soap:body parts="parameters" use="literal"/>
</output>
</operation>
</binding>
<service name="PK_NATIVE_WS_TESTService">
<documentation>Oracle Web Service</documentation>
<port name="PK_NATIVE_WS_TESTPort" binding="tns:PK_NATIVE_WS_TESTBinding">
<soap:address
location="http://******:8080/orawsv/WS_SOAP_TEST/PK_NATIVE_WS_TEST"/>
</port>
</service>
</definitions>
Pour tester le service, créez un nouveau projet SOAP dans l'interface utilisateur SOAP. En tant qu'URL, spécifiez l'adresse dans l'exemple ci-dessus.à l'ouverture, Request 1
nous voyons que le modĂšle de demande est dĂ©jĂ gĂ©nĂ©rĂ© automatiquement par le WSDL spĂ©cifiĂ©.Ajoutez immĂ©diatement l'autorisation de base pour la demande - le login et le mot de passe sont les mĂȘmes que lors de la connexion Ă la base de donnĂ©es.
Exemple de demande et de réponse. Veuillez noter qu'une ligne a été ajoutée à la demande générée automatiquement <pk:O_RESULT-VARCHAR2-OUT/>
. Le fait est qu'il y a un bogue dans Oracle 12c: les variables OUT ne sont pas ajoutées au WSDL pour Native Oracle WS).
Le résultat de l'appel est visible dans la table des journaux.
résultats
La technologie native Oracle XML DB Web Services peut ĂȘtre utilisĂ©e comme une solution industrielle Ă condition qu'il n'y ait pas de charge importante sur ce service Web (une demande en quelques secondes). Cette option convient lorsque les consommateurs n'ont pas d'exigences strictes pour un service Web (ses attributs, structures de donnĂ©es, logique de traitement) et qu'il n'y a pas de contrat prĂ©dĂ©terminĂ© strict. Si vous devez crĂ©er un service Web selon un WSDL prĂ©dĂ©fini (comme dans notre cas avec un nouvel Ă©quipement), la technologie Native Oracle WS ne sera pas adaptĂ©e.Service de donnĂ©es Oracle REST
Ă partir de la version 11.1, Oracle a introduit la prise en charge complĂšte de RESTful sous la forme d'un module distinct appelĂ© Oracle REST Data Service (ORDS).ORDS est une application Java qui vous permet de crĂ©er une API RESTful pour une base de donnĂ©es Oracle Ă l'aide de SQL et PL / SQL. C'est une alternative Ă l'utilisation d'Oracle HTTP Server et de mod_plsql. En substance, ORDS est une interface HTTP entre le monde extĂ©rieur et une base de donnĂ©es Oracle. Cette interface vous permet de fermer les requĂȘtes HTTP entrantes Ă n'importe quel objet de base de donnĂ©es - une table ou une procĂ©dure PL / SQL.Il suffit d'installer, de configurer et d'exĂ©cuter ORDS pour la base de donnĂ©es requise. Le processus supplĂ©mentaire de crĂ©ation de services REST se rĂ©sume Ă l'Ă©criture de code en PL / SQL (ou mĂȘme en cliquant dans l'IDE si le code est trop paresseux pour ĂȘtre Ă©crit).Aucune licence supplĂ©mentaire n'est requise pour installer ORDS.Exigences:- Java JDK 8 ou supĂ©rieur;
- Oracle 11.1 ou version ultérieure (Oracle 11 XE Release 2 est également pris en charge).
Plusieurs options de déploiement ORDS sont prises en charge:- mode autonome;
- sur le serveur d'applications (Oracle WebLogic Server, Apache Tomcat).
Capacités
ORDS vous permet de:- Organisez l'accĂšs aux ressources dans un style RESTful.
- Créez une interaction dans le style "Appel de procédure distante" (interaction de style RPC).
En termes simples, avec l'aide d'ORDS, vous pouvez ouvrir l'accĂšs via HTTP Ă certains objets de base de donnĂ©es - tables, procĂ©dures, fonctions, packages.Dans le premier cas, nous avons affaire Ă des ressources dans le sens oĂč elles sont comprises dans le style architectural RESTful. Chaque ressource est dĂ©finie par un URI unique et les opĂ©rations avec des ressources (CRUD - crĂ©er, lire, modifier, supprimer) sont dĂ©terminĂ©es par les opĂ©rations de la requĂȘte HTTP: PUT, POST, GET, DELETE. Par exemple, si la ressource est une entrĂ©e dans la table des employĂ©s, cette entrĂ©e sera disponible par un URI du formulaire:GET https://server:port/ords/workspace/hr/employees/7369
Ici, le nom du schĂ©ma de base de donnĂ©es, le nom de la table et l'ID d'enregistrement dans la table sont indiquĂ©s dans l'URI. Ainsi, cette demande HTTP effectue en fait une opĂ©ration SELECT Ă partir de la table spĂ©cifiĂ©e. Avec d'autres opĂ©rations (ajout, modification, suppression), le principe de communication est le mĂȘme: le chemin d'accĂšs Ă la ressource est indiquĂ© dans l'URI, et des paramĂštres supplĂ©mentaires sont indiquĂ©s dans le corps de la demande, par exemple, des valeurs de champ pour insĂ©rer un enregistrement dans la table.Dans le second cas, au lieu d'accĂ©der Ă la ressource, un appel de procĂ©dure est directement utilisĂ©, qui peut tout faire de la mĂȘme maniĂšre que dans le premier cas (CRUD), ainsi que d'exĂ©cuter toute autre logique qui implĂ©mente le processus mĂ©tier nĂ©cessaire. Un appel de procĂ©dure Ă partir d'un package peut ĂȘtre effectuĂ© Ă l'aide d'une requĂȘte HTTP de ce format:http://localhost:8080/ords/my_schema/my_pkg/MY_PROC
Les paramÚtres de la procédure sont transférés dans le corps de la demande sous la forme de structures au format JSON {"param" : "value"}
. La mĂȘme approche est utilisĂ©e lors de l'utilisation du WS Oracle natif, dĂ©crite ci-dessus, mais dans le cas des services REST, aucune restriction n'est imposĂ©e par le protocole SOAP.avantages- Un mĂ©canisme flexible qui vous permet de mettre en Ćuvre des services Web de toute complexitĂ©.
- SimplicitĂ© de mise en Ćuvre: pour transformer une procĂ©dure PL / SQL en service Web, vous devez exĂ©cuter seulement quelques commandes typiques. Et Ă l'aide de SQL Developer, la crĂ©ation d'une API REST se transforme en un clic de souris avec un minimum d'Ă©criture de code.
- La possibilité d'implémenter un service Web sans authentification.
Moins- ORDS n'est pas inclus dans le package Oracle standard - il doit ĂȘtre installĂ© sĂ©parĂ©ment pour chaque serveur (des licences supplĂ©mentaires, comme dĂ©jĂ mentionnĂ©, ne sont pas nĂ©cessaires). Cela peut ĂȘtre un problĂšme si vous avez des milliers de serveurs de base de donnĂ©es.
Personnalisation
ORDS peut ĂȘtre lancĂ© en deux modes: via le serveur d'applications ou en mode autonome.Cet article traite uniquement de l'option Ă exĂ©cuter en mode autonome.Pour que ORDS fonctionne, vous avez besoin de:- Configurez les paramĂštres avant l'installation.
- Terminez l'installation d'ODRS.
- Lancez ORDS.
- Configurez ACL (pour le schéma de base de données souhaité).
Réglages
La distribution ORDS a un fichier avec des paramÚtres qui ressemble à ceci par défaut:db.hostname=
db.port=
db.servicename=
db.sid=
db.username=APEX_PUBLIC_USER
migrate.apex.rest=false
rest.services.apex.add=
rest.services.ords.add=true
schema.tablespace.default=SYSAUX
schema.tablespace.temp=TEMP
standalone.http.port=8080
standalone.static.images=
user.tablespace.default=USERS
user.tablespace.temp=TEMP
Une description des paramĂštres peut ĂȘtre trouvĂ©e dans la documentationParamĂštres pour le mode autonome:Par consĂ©quent, le contenu du fichier devrait ressembler Ă ceci:db.hostname=your_server_host_name
db.port=1521
db.servicename=your_db_servicename
migrate.apex.rest=false
rest.services.apex.add=false
rest.services.ords.add=true
schema.tablespace.default=SYSAUX
schema.tablespace.temp=TEMP
standalone.http.port=8888
standalone.static.images=
user.tablespace.default=USERS
user.tablespace.temp=TEMP
Les réglages nécessaires sont terminés, vous pouvez procéder à l'installation.Installation
Nous exécutons la commande dans l'OS:java -jar ords.war
Par défaut, le fichier de configuration est extrait du répertoire params
situé à cÎté de ords.war
. Vous pouvez spécifier explicitement le chemin d'accÚs à ce fichier à l'aide du paramÚtre --parameterFile
:java -jar ords.war --parameterFile /path/to/params/myown_params.properties
Dans la boßte de dialogue d'installation, procédez comme suit:- Nous indiquons le chemin d'accÚs au répertoire pour enregistrer la configuration (dans l'exemple, il est indiqué
conf
- en consĂ©quence, dans le mĂȘme rĂ©pertoire oĂč se trouve le fichier ords.war
, un répertoire sera créé conf
dans lequel les fichiers avec la configuration ORDS seront créés). - AprÚs que la commande Entrez le mot de passe de la base de données pour ORDS_PUBLIC_USER s'affiche, nous entrons le mot de passe pour le schéma
ORDS_PUBLIC_USER
. Sous cet utilisateur, ORDS se connectera à la base de données. - AprÚs que l'invite Entrez 1 si vous souhaitez utiliser PL / SQL Gateway ou 2 pour ignorer cette étape s'affiche, nous répondons «2», car nous n'allons pas utiliser APEX et nous n'avons pas besoin de migrer depuis
mod_plsql
. - AprÚs que l'instruction Enter 1 si vous souhaitez démarrer en mode autonome ou 2 pour quitter [1] apparaisse, nous répondons «1».
- AprÚs que l'instruction Enter 1 if using HTTP or 2 if using HTTPS [1] s'affiche, nous répondons 1.
BoĂźte de dialogue d'installationD:\ords-19.2.0.199.1647>java -jar ords.war install
This Oracle REST Data Services instance has not yet been configured.
Please complete the following prompts
Enter the location to store configuration data: conf
Enter the database password for ORDS_PUBLIC_USER:
Confirm password:
03, 2019 2:47:49 PM oracle.dbtools.rt.config.setup.SchemaSetup getInstallOrUpgrade
WARNING: Failed to connect to user ORDS_PUBLIC_USER jdbc:oracle:thin:@//***YOUR_HOST_NAME.DOMAIN***:1521/***YOUR_SERVICE_NAME.DOMAIN***
Enter 1 if you want to use PL/SQL Gateway or 2 to skip this step.
If using Oracle Application Express or migrating from mod_plsql then you must enter 1 [1]:2
03, 2019 2:48:32 PM
INFO: reloaded pools: []
Enter 1 if you wish to start in standalone mode or 2 to exit [1]:
Enter 1 if using HTTP or 2 if using HTTPS [1]:
2019-09-03 14:48:49.754:INFO::main: Logging initialized @4276887ms to org.eclipse.jetty.util.log.StdErrLog
03, 2019 2:48:49 PM
INFO: HTTP and HTTP/2 cleartext listening on port: 8082
03, 2019 2:48:50 PM
INFO: Disabling document root because the specified folder does not exist: D:\ords-19.2.0.199.1647\conf\ords\standalone\doc_root
Exception in thread "main" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at oracle.dbtools.jarcl.Entrypoint.invoke(Entrypoint.java:66)
at oracle.dbtools.jarcl.Entrypoint.main(Entrypoint.java:89)
Caused by: java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Unknown Source)
at java.lang.AbstractStringBuilder.ensureCapacityInternal(Unknown Source)
at java.lang.AbstractStringBuilder.append(Unknown Source)
at java.lang.StringBuilder.append(Unknown Source)
at java.lang.StringBuilder.append(Unknown Source)
at java.util.AbstractMap.toString(Unknown Source)
at java.lang.String.valueOf(Unknown Source)
at java.lang.StringBuilder.append(Unknown Source)
at oracle.dbtools.jarcl.zip.ZipIndex.toString(ZipIndex.java:166)
at java.lang.String.valueOf(Unknown Source)
at java.lang.StringBuilder.append(Unknown Source)
at oracle.dbtools.jarcl.JarClassLoader.toString(JarClassLoader.java:51)
at org.eclipse.jetty.server.ClassLoaderDump.dump(ClassLoaderDump.java:67)
at org.eclipse.jetty.util.component.Dumpable.dumpObjects(Dumpable.java:225)
at org.eclipse.jetty.util.component.ContainerLifeCycle.dumpObjects(ContainerLifeCycle.java:746)
at org.eclipse.jetty.server.handler.ContextHandler.dump(ContextHandler.java:259)
at org.eclipse.jetty.util.component.Dumpable.dumpObjects(Dumpable.java:162)
at org.eclipse.jetty.util.component.ContainerLifeCycle.dumpObjects(ContainerLifeCycle.java:746)
at org.eclipse.jetty.util.component.ContainerLifeCycle.dump(ContainerLifeCycle.java:701)
at org.eclipse.jetty.util.component.Dumpable.dump(Dumpable.java:62)
at org.eclipse.jetty.util.component.ContainerLifeCycle.dump(ContainerLifeCycle.java:684)
at oracle.dbtools.standalone.StandaloneConfiguration.start(StandaloneConfiguration.java:241)
at oracle.dbtools.standalone.Standalone.execute(Standalone.java:508)
at oracle.dbtools.cmdline.DefaultCommand.execute(DefaultCommand.java:137)
at oracle.dbtools.cmdline.Commands.execute(Commands.java:207)
at oracle.dbtools.cmdline.Commands.main(Commands.java:163)
at oracle.dbtools.cmdline.Commands.main(Commands.java:368)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at oracle.dbtools.jarcl.Entrypoint.invoke(Entrypoint.java:66)
En conséquence, un répertoire avec la configuration ORDS sera créé et les schémas d'utilitaires pour ORDS apparaßtront dans la base de données.Voir également: Installez Oracle REST Data Services 3.0.X en moins de 5 minutes .lancement
Le démarrage en mode autonome s'effectue par la commande:java -jar ords.war standalone
BoĂźte de dialogue de lancementD:\ords-19.2.0.199.1647>java -jar ords.war standalone
2019-09-03 15:52:45.825:INFO::main: Logging initialized @2079ms to org.eclipse.jetty.util.log.StdErrLog
03, 2019 3:52:45 PM
INFO: HTTP and HTTP/2 cleartext listening on port: 8082
03, 2019 3:52:45 PM
INFO: Disabling document root because the specified folder does not exist: D:\ords-19.2.0.199.1647\conf\ords\standalone\doc_root
2019-09-03 15:52:47.124:INFO:oejs.Server:main: jetty-9.4.z-SNAPSHOT; built: 2019-05-02T09:46:34.874Z; git: 14f32d50076f2b706f41a33066eb364d8492e199; jvm 1.8.0_221-b11
2019-09-03 15:52:47.179:INFO:oejs.session:main: DefaultSessionIdManager workerName=node0
2019-09-03 15:52:47.179:INFO:oejs.session:main: No SessionScavenger set, using defaults
2019-09-03 15:52:47.180:INFO:oejs.session:main: node0 Scavenging every 660000ms
03, 2019 3:52:48 PM
INFO: Configuration properties for: |apex|pu|
db.hostname=***YOUR_HOST_NAME.DOMAIN***
db.password=******
db.port=1521
db.servicename=***YOUR_SERVICE_NAME.DOMAIN***
db.username=ORDS_PUBLIC_USER
resource.templates.enabled=true
03, 2019 3:52:48 PM
WARNING: *** jdbc.MaxLimit in configuration |apex|pu| is using a value of 10, this setting may not be sized adequately for a production environment ***
03, 2019 3:52:48 PM
WARNING: *** jdbc.InitialLimit in configuration |apex|pu| is using a value of 3, this setting may not be sized adequately for a production environment ***
03, 2019 3:52:50 PM
INFO: Oracle REST Data Services initialized
Oracle REST Data Services version : 19.2.0.r1991647
Oracle REST Data Services server info: jetty/9.4.z-SNAPSHOT
2019-09-03 15:52:50.484:INFO:oejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler@d56d67{/ords,null,AVAILABLE}
2019-09-03 15:52:50.658:INFO:oejs.AbstractConnector:main: Started ServerConnector@12325ad{HTTP/1.1,[http/1.1, h2c]}{0.0.
0.0:8082}
2019-09-03 15:52:50.659:INFO:oejs.Server:main: Started @6914ms
AprĂšs cela, ORDS est opĂ©rationnel. L'adresse du service Web sera http: // <nom d'hĂŽte>: / ords / ..., oĂč <nom d'hĂŽte> est le nom de l'ordinateur exĂ©cutant ORDS (il ne doit pas nĂ©cessairement correspondre au nom du serveur de base de donnĂ©es, c'est-Ă -dire que ORDS peut ĂȘtre exĂ©cutĂ© sur un autre hĂŽte ), <port> - le port spĂ©cifiĂ© dans la configuration ORDS.Si vous le souhaitez, vous pouvez crĂ©er un script pour exĂ©cuter automatiquement ORDS au dĂ©marrage du systĂšme d'exploitation.ParamĂštre d'accĂšs
Et la derniĂšre Ă©tape consiste Ă configurer l'ACL. Les Ă©tapes sont les mĂȘmes que pour l'utilisation d'Oracle WS natif.Vous devez effectuer cette Ă©tape aprĂšs la crĂ©ation du schĂ©ma de base de donnĂ©es, de sorte que les exemples ci-dessous indiquent sĂ©parĂ©ment quand vous devez effectuer cette configuration. Jusqu'Ă prĂ©sent, nous pouvons supposer que toutes les Ă©tapes prĂ©liminaires ont Ă©tĂ© achevĂ©es et poursuivre avec les exemples.Exemple 1: gestionnaire d'une demande POST
Par exemple, considérons l'option d'implémentation d'interaction de style RPC, c'est-à -dire que nous allons créer une méthode de service Web, dont le gestionnaire sera une procédure par lots.En effet, c'est dans cette version que le travail avec ORDS a été implémenté dans notre projet de réseau de distribution, et le résultat a répondu à ses attentes. Il s'est avéré un moyen rapide et universel de créer de nouvelles méthodes de services Web pour différents processus métier - du travail avec l'équipement à l'API pour les sites.Comme mentionné ci-dessus, le support ORDS est également inclus dans SQL Developer (l'EDI de base de données développé par Oracle). Dans SQL Developer, la création de services Web est disponible directement à partir des éléments de menu ou du menu contextuel.Dans cet article, des exemples sont réalisés à l'aide de SQL Developer (version 18), mais le code PL / SQL qui est exécuté dans la base de données à la suite d'actions dans l'IDE est également inclus.La version de la base de données sur laquelle les expériences ont été effectuées:SQL> SELECT v.BANNER FROM v$version v;
BANNER
Oracle DATABASE 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
PL/SQL Release 12.2.0.1.0 - Production
CORE 12.2.0.1.0 Production
TNS FOR Linux: Version 12.2.0.1.0 - Production
NLSRTL Version 12.2.0.1.0 - Production
Création d'un utilisateur de test pour WS
Par exemple, nous avons à nouveau besoin d'un nouveau schéma - créez-le:CREATE USER WS_TEST IDENTIFIED BY ws_test QUOTA 200M ON USERS;
GRANT CREATE SESSION, RESOURCE TO ws_test;
Configuration d'un schéma de base de données
Une fois le diagramme créé, il est nécessaire de le rendre accessible via ORDS.Pour ça:- Dans SQL Developer, créez une connexion pour
WS_TEST
. - Dans la liste des connexions, appelez le menu contextuel de la nouvelle connexion. Choisissez Services REST â Activer les services REST ... :

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

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

Référencement:BEGIN
ORDS.ENABLE_SCHEMA( p_enabled => TRUE
, p_schema => 'WS_TEST'
, p_url_mapping_type => 'BASE_PATH'
, p_url_mapping_pattern => 'ws_test'
, p_auto_rest_auth => FALSE);
COMMIT;
END;
/
Création d'un module et d'un modÚle
Ensuite, vous devez créer un module et un modÚle pour la ressource.Un module est une unité structurelle qui vous permet de regrouper plusieurs modÚles de ressources logiquement liés.Un modÚle est un service Web spécifique servant un ensemble spécifique de méthodes pour une ressource.à la source :module de ressources: unité organisationnelle utilisée pour regrouper les modÚles de ressources associés.
ModĂšle de ressource: service RESTful individuel capable de traiter les demandes d'un certain ensemble d'URI (Universal Resource Identifiers). L'ensemble d'URI est dĂ©fini par le modĂšle d'URI du modĂšle de ressource.Par exemple, pour une boutique en ligne, un module peut ĂȘtre appelĂ©shop
- dans ce module, toutes les API du magasin seront combinĂ©es. Les modĂšles peuvent ĂȘtre des ressources spĂ©cifiques, par exemple, une commande (modĂšle order
), un catalogue de produits (modĂšle item
), un paiement (modĂšle payment
), etc.Pour créer un module et un modÚle, vous devez effectuer les étapes suivantes:- Dans l'arborescence d'objets, ouvrez la section REST Data Services, appelez le menu contextuel dans la section Modules , sélectionnez Nouveau module ... :

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

- Dans la boßte de dialogue suivante, spécifiez le nom du modÚle, par exemple
order
, et cliquez Ă nouveau sur "Suivant>" .
Dans la derniÚre boßte de dialogue, nous voyons tous les paramÚtres saisis du module et du modÚle. Sous l'onglet SQL , vous pouvez voir le code PL / SQL qui sera exécuté dans la base de données lorsque vous cliquez sur Terminer :

Pour créer un module shop
, vous pouvez ajouter plusieurs motifs - également dans l'arborescence d'objets, le menu contextuel et en sélectionnant le modÚle ... Ajouter le .Liste de code pour créer un module et un modÚleBEGIN
ORDS.DEFINE_MODULE( p_module_name => 'shop'
, p_base_path => 'shop'
, p_items_per_page => 25
, p_status => 'PUBLISHED'
, p_comments => NULL);
ORDS.DEFINE_TEMPLATE( p_module_name => 'shop'
, p_pattern => 'order'
, p_priority => 0
, p_etag_type => 'HASH'
, p_etag_query => NULL
, p_comments => NULL);
COMMIT;
END;
/
CrĂ©ation d'un gestionnaire de requĂȘtes HTTP
Nous devons maintenant crĂ©er un gestionnaire de requĂȘtes HTTP pour notre service.Tout d'abord, nous devons crĂ©er des objets de base de donnĂ©es qui contiendront la logique de traitement des demandes.Nous avons besoin d'une table de journalisation et d'un package dans lequel il y aura un code de gestionnaire.CrĂ©ez une table Ă l'aide d'un script:CREATE TABLE T_WS_LOG
(
id_log NUMBER GENERATED ALWAYS AS IDENTITY,
message VARCHAR2(2000),
request_header VARCHAR2(2000),
request_body CLOB,
response_header VARCHAR2(2000),
response_body CLOB,
dtz_log TIMESTAMP(6) WITH TIME ZONE DEFAULT SYSTIMESTAMP
);
COMMENT ON TABLE T_WS_LOG IS ' HTTP- (ORDS)';
COMMENT ON COLUMN T_WS_LOG.id_log IS '';
COMMENT ON COLUMN T_WS_LOG.message IS ' ';
COMMENT ON COLUMN T_WS_LOG.request_header IS ' ';
COMMENT ON COLUMN T_WS_LOG.request_body IS ' ';
COMMENT ON COLUMN T_WS_LOG.response_header IS ' ';
COMMENT ON COLUMN T_WS_LOG.response_body IS ' ';
COMMENT ON COLUMN T_WS_LOG.dtz_log IS '/ ';
ALTER TABLE T_WS_LOG ADD CONSTRAINT PK_T_WS_LOG PRIMARY KEY (ID_LOG) USING INDEX;
Créez un package:CREATE OR REPLACE PACKAGE PK_ORDS_API IS
FUNCTION blob2clob
( a_blob BLOB
, a_from_charset VARCHAR2 := 'AMERICAN_AMERICA.AL32UTF8'
, a_to_charset VARCHAR2 := 'AMERICAN_AMERICA.AL32UTF8'
) RETURN CLOB;
PROCEDURE process_request
( a_request CLOB
);
END PK_ORDS_API;
/
CREATE OR REPLACE PACKAGE BODY PK_ORDS_API IS
FUNCTION blob2clob
( a_blob BLOB
, a_from_charset VARCHAR2 := 'AMERICAN_AMERICA.AL32UTF8'
, a_to_charset VARCHAR2 := 'AMERICAN_AMERICA.AL32UTF8'
) RETURN CLOB
AS
l_clob CLOB;
l_amount NUMBER := 2000;
l_offset NUMBER := 1;
l_buffer VARCHAR2(32767);
l_length PLS_INTEGER := dbms_lob.getlength(a_blob);
BEGIN
dbms_lob.createtemporary(l_clob, TRUE);
dbms_lob.OPEN(l_clob, dbms_lob.lob_readwrite);
WHILE l_offset <= l_length LOOP
l_buffer := UTL_RAW.cast_to_varchar2(UTL_RAW.convert( r => dbms_lob.substr(a_blob, l_amount, l_offset)
, from_charset => a_from_charset
, to_charset => a_to_charset));
IF LENGTH(l_buffer) > 0 THEN
dbms_lob.writeappend(l_clob, LENGTH(l_buffer), l_buffer);
END IF;
l_offset := l_offset + l_amount;
EXIT WHEN l_offset > l_length;
END LOOP;
RETURN l_clob;
END blob2clob;
PROCEDURE process_request
( a_request CLOB
)
AS
TYPE TStringHash IS TABLE OF VARCHAR2(256) INDEX BY VARCHAR2(256);
lh_hdr TStringHash;
l_hdr VARCHAR2(256);
l_resp CLOB;
l_response_status INTEGER := 200;
l_ccontent_type VARCHAR2(64) := 'application/json';
l_in_headers VARCHAR2(32767);
BEGIN
lh_hdr('SERVER_SOFTWARE') := OWA_UTIL.get_cgi_env('SERVER_SOFTWARE');
lh_hdr('SERVER_NAME') := OWA_UTIL.get_cgi_env('SERVER_NAME');
lh_hdr('GATEWAY_INTERFACE') := OWA_UTIL.get_cgi_env('GATEWAY_INTERFACE');
lh_hdr('SERVER_PROTOCOL') := OWA_UTIL.get_cgi_env('SERVER_PROTOCOL');
lh_hdr('SERVER_PORT') := OWA_UTIL.get_cgi_env('SERVER_PORT');
lh_hdr('REQUEST_METHOD') := OWA_UTIL.get_cgi_env('REQUEST_METHOD');
lh_hdr('PATH_INFO') := OWA_UTIL.get_cgi_env('PATH_INFO');
lh_hdr('PATH_TRANSLATED') := OWA_UTIL.get_cgi_env('PATH_TRANSLATED');
lh_hdr('SCRIPT_NAME') := OWA_UTIL.get_cgi_env('SCRIPT_NAME');
lh_hdr('QUERY_STRING') := OWA_UTIL.get_cgi_env('QUERY_STRING');
lh_hdr('REMOTE_HOST') := OWA_UTIL.get_cgi_env('REMOTE_HOST');
lh_hdr('REMOTE_ADDR') := OWA_UTIL.get_cgi_env('REMOTE_ADDR');
lh_hdr('AUTH_TYPE') := OWA_UTIL.get_cgi_env('AUTH_TYPE');
lh_hdr('REMOTE_USER') := OWA_UTIL.get_cgi_env('REMOTE_USER');
lh_hdr('REMOTE_IDENT') := OWA_UTIL.get_cgi_env('REMOTE_IDENT');
lh_hdr('CONTENT-TYPE') := OWA_UTIL.get_cgi_env('CONTENT-TYPE');
lh_hdr('CONTENT-LENGTH') := OWA_UTIL.get_cgi_env('CONTENT-LENGTH');
lh_hdr('HTTP_ACCEPT') := OWA_UTIL.get_cgi_env('HTTP_ACCEPT');
lh_hdr('HTTP_ACCEPT_LANGUAGE') := OWA_UTIL.get_cgi_env('HTTP_ACCEPT_LANGUAGE');
lh_hdr('HTTP_USER_AGENT') := OWA_UTIL.get_cgi_env('HTTP_USER_AGENT');
lh_hdr('HTTP_COOKIE') := OWA_UTIL.get_cgi_env('HTTP_COOKIE');
l_hdr := lh_hdr.FIRST;
WHILE l_hdr IS NOT NULL LOOP
IF lh_hdr(l_hdr) IS NOT NULL THEN
l_in_headers := l_in_headers||CHR(10)||l_hdr||': '||lh_hdr(l_hdr);
END IF;
l_hdr := lh_hdr.NEXT(l_hdr);
END LOOP;
l_resp := '{ "result" : "success" }';
INSERT INTO t_ws_log
( message
, request_header
, request_body
, response_header
, response_body)
VALUES
( NULL
, l_in_headers
, a_request
, 'Content-Type: '||l_ccontent_type
, l_resp
);
OWA_UTIL.STATUS_LINE(nstatus => l_response_status, bclose_header => FALSE);
OWA_UTIL.MIME_HEADER(ccontent_type => l_ccontent_type, bclose_header => FALSE);
OWA_UTIL.HTTP_HEADER_CLOSE();
htp.p(l_resp);
END process_request;
END PK_ORDS_API;
/
Maintenant, pour le modÚle créé, vous devez ajouter un gestionnaire. Ajoutez un gestionnaire pour la méthode HTTP POST
.Pour ce faire, procédez comme suit:- Nous appelons le menu contextuel du modÚle, sélectionnez Ajouter un gestionnaire , puis sélectionnez la méthode 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;
Si nĂ©cessaire, vous pouvez obtenir le code PL / SQL pour crĂ©er un gestionnaire. Pour ce faire, dans le menu contextuel du module ORDS, sĂ©lectionnez DĂ©finition REST puis spĂ©cifiez oĂč sortir le script de crĂ©ation de module, par exemple, dans le presse-papiers:

Le code résultant pour créer le module
BEGIN
ORDS.ENABLE_SCHEMA(
p_enabled => TRUE,
p_schema => 'WS_TEST',
p_url_mapping_type => 'BASE_PATH',
p_url_mapping_pattern => 'ws_test',
p_auto_rest_auth => TRUE);
ORDS.DEFINE_MODULE(
p_module_name => 'shop',
p_base_path => '/shop/',
p_items_per_page => 25,
p_status => 'PUBLISHED',
p_comments => NULL);
ORDS.DEFINE_TEMPLATE(
p_module_name => 'shop',
p_pattern => 'order',
p_priority => 0,
p_etag_type => 'HASH',
p_etag_query => NULL,
p_comments => NULL);
ORDS.DEFINE_HANDLER(
p_module_name => 'shop',
p_pattern => 'order',
p_method => 'POST',
p_source_type => 'plsql/block',
p_items_per_page => 0,
p_mimes_allowed => '',
p_comments => NULL,
p_source =>
'DECLARE
l_blob BLOB := :body;
BEGIN
PK_ORDS_API.process_request(a_request => PK_ORDS_API.blob2clob(l_blob));
EXCEPTION
WHEN OTHERS THEN
OWA_UTIL.STATUS_LINE(nstatus => 500, bclose_header => FALSE);
OWA_UTIL.MIME_HEADER(ccontent_type => ''application/json'');
htp.p(''{ "result" : "error", "message" : "''||SQLERRM||''" }'');
END;'
);
COMMIT;
END;
Remarque: si vous exécutez à ORDS.DEFINE_MODULE
nouveau la procédure de création de module , tous les modÚles de ce module seront automatiquement supprimés et il n'y aura aucun avertissement à ce sujet!Exemple d'appel
C'est lĂ que notre service Web est prĂȘt. Reste Ă vĂ©rifier son travail.Pour vĂ©rifier, nous exĂ©cutons la demande:POST http://****:8888/ords/ws_test/shop/order HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: application/json
Content-Length: 22
Host: ****:8888
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
{ "message" : "test" }
En réponse, nous obtenons:HTTP/1.1 200 OK
Date: Wed, 23 Oct 2019 16:54:53 GMT
Content-Type: application/json
Transfer-Encoding: chunked
{ "result" : "success" }
Le résultat de l'exécution de la méthode est une entrée avec le corps de la demande et la réponse dans la table du journal:
Comme vous pouvez le voir, la demande HTTP envoyée a été traitée avec succÚs par la procédure à partir du paquet.ParamÚtres de la demande
Ci-dessus, nous avons déjà vu le résultat d'un simple service web. Maintenant, compliquons un peu la tùche en ajoutant des paramÚtres supplémentaires à la demande.Il existe deux façons de transmettre des paramÚtres:Via l'URL. Les paramÚtres sont définis dans l'URL sous la forme standard:http://...URI...?p1=val1&p2=val2
Via HEADER. Les paramĂštres sont dĂ©finis dans l'en-tĂȘte de la demande comme p1: val1
Dans ORDS dans le gestionnaire de demandes, les paramÚtres sont définis comme des variables de liaison.Nous ajoutons deux paramÚtres à l'exemple précédent: prm1
- paramĂštre dans l'URI, prm2
- paramĂštre dans l'en-tĂȘte de la requĂȘte.Pour traiter ces paramĂštres, PK_ORDS_API.process_request:
nous ajoutons la procédure, ajoutons les paramÚtres a_prm_uri
et a_prm_hdr
, Ă laquelle viendront les valeurs de nos paramĂštres de la requĂȘte.ProcĂ©dure de gestion des requĂȘtes avec de nouveaux paramĂštresPROCEDURE process_request
( a_request CLOB
, a_prm_uri VARCHAR2 := NULL
, a_prm_hdr VARCHAR2 := NULL
)
AS
TYPE TStringHash IS TABLE OF VARCHAR2(256) INDEX BY VARCHAR2(256);
lh_hdr TStringHash;
l_hdr VARCHAR2(256);
l_resp CLOB;
l_response_status INTEGER := 200;
l_ccontent_type VARCHAR2(64) := 'application/json';
l_in_headers VARCHAR2(32767);
BEGIN
lh_hdr('SERVER_SOFTWARE') := OWA_UTIL.get_cgi_env('SERVER_SOFTWARE');
lh_hdr('SERVER_NAME') := OWA_UTIL.get_cgi_env('SERVER_NAME');
lh_hdr('GATEWAY_INTERFACE') := OWA_UTIL.get_cgi_env('GATEWAY_INTERFACE');
lh_hdr('SERVER_PROTOCOL') := OWA_UTIL.get_cgi_env('SERVER_PROTOCOL');
lh_hdr('SERVER_PORT') := OWA_UTIL.get_cgi_env('SERVER_PORT');
lh_hdr('REQUEST_METHOD') := OWA_UTIL.get_cgi_env('REQUEST_METHOD');
lh_hdr('PATH_INFO') := OWA_UTIL.get_cgi_env('PATH_INFO');
lh_hdr('PATH_TRANSLATED') := OWA_UTIL.get_cgi_env('PATH_TRANSLATED');
lh_hdr('SCRIPT_NAME') := OWA_UTIL.get_cgi_env('SCRIPT_NAME');
lh_hdr('QUERY_STRING') := OWA_UTIL.get_cgi_env('QUERY_STRING');
lh_hdr('REMOTE_HOST') := OWA_UTIL.get_cgi_env('REMOTE_HOST');
lh_hdr('REMOTE_ADDR') := OWA_UTIL.get_cgi_env('REMOTE_ADDR');
lh_hdr('AUTH_TYPE') := OWA_UTIL.get_cgi_env('AUTH_TYPE');
lh_hdr('REMOTE_USER') := OWA_UTIL.get_cgi_env('REMOTE_USER');
lh_hdr('REMOTE_IDENT') := OWA_UTIL.get_cgi_env('REMOTE_IDENT');
lh_hdr('CONTENT-TYPE') := OWA_UTIL.get_cgi_env('CONTENT-TYPE');
lh_hdr('CONTENT-LENGTH') := OWA_UTIL.get_cgi_env('CONTENT-LENGTH');
lh_hdr('HTTP_ACCEPT') := OWA_UTIL.get_cgi_env('HTTP_ACCEPT');
lh_hdr('HTTP_ACCEPT_LANGUAGE') := OWA_UTIL.get_cgi_env('HTTP_ACCEPT_LANGUAGE');
lh_hdr('HTTP_USER_AGENT') := OWA_UTIL.get_cgi_env('HTTP_USER_AGENT');
lh_hdr('HTTP_COOKIE') := OWA_UTIL.get_cgi_env('HTTP_COOKIE');
lh_hdr('a_prm_uri') := a_prm_uri;
lh_hdr('a_prm_hdr') := a_prm_hdr;
l_hdr := lh_hdr.FIRST;
WHILE l_hdr IS NOT NULL LOOP
IF lh_hdr(l_hdr) IS NOT NULL THEN
l_in_headers := l_in_headers||CHR(10)||l_hdr||': '||lh_hdr(l_hdr);
END IF;
l_hdr := lh_hdr.NEXT(l_hdr);
END LOOP;
l_resp := '{ "result" : "success" }';
INSERT INTO t_ws_log
( message
, request_header
, request_body
, response_header
, response_body)
VALUES
( NULL
, l_in_headers
, a_request
, 'Content-Type: '||l_ccontent_type
, l_resp);
OWA_UTIL.STATUS_LINE(nstatus => l_response_status, bclose_header => FALSE);
OWA_UTIL.MIME_HEADER(ccontent_type => l_ccontent_type, bclose_header => FALSE);
OWA_UTIL.HTTP_HEADER_CLOSE();
htp.p(l_resp);
END process_request;
Dans la procĂ©dure, nous enregistrons simplement les valeurs des nouveaux paramĂštres dans le journal.Ajoutez de nouveaux paramĂštres au gestionnaire de requĂȘtes POST - sous la forme de variables de liaison :prm_uri
et :prm_hdr
.Gestionnaire de la demande de requĂȘte POST avec de nouveaux paramĂštres:DECLARE
l_blob BLOB := :body;
BEGIN
PK_ORDS_API.process_request(a_request => PK_ORDS_API.blob2clob(l_blob), a_prm_uri => :prm_uri, a_prm_hdr => :prm_hdr);
EXCEPTION
WHEN OTHERS THEN
OWA_UTIL.STATUS_LINE(nstatus => 500, bclose_header => FALSE);
OWA_UTIL.MIME_HEADER(ccontent_type => 'application/json');
htp.p('{ "result" : "error", "message" : "'||SQLERRM||'" }');
END;
Dans le gestionnaire, sous l'onglet ParamÚtres , déclarez les variables: sous
cette forme, le premier champ ( nom ) contient le nom du paramÚtre attendu dans la demande, le deuxiÚme champ ( paramÚtre de liaison) - le nom de la variable de liaison qui sera spécifiée dans le gestionnaire de cette demande.Exécutons la demande avec de nouveaux paramÚtres:
Résultat - les paramÚtres de la demande ont été enregistrés dans le journal:
Veuillez noter que les paramĂštres de l'URI peuvent Ă©galement ĂȘtre rĂ©cupĂ©rĂ©s Ă partir de la variable CGI QUERY_STRING
, c'est-à -dire que pour obtenir les paramÚtres, il n'est pas nécessaire de démarrer les variables de liaison - vous pouvez les analyser dans la procédure du gestionnaire demande.Variables CGI
Lorsque vous travaillez avec HTTP dans Oracle, il est possible d'obtenir les valeurs des variables d'environnement qui reflÚtent le contexte de la demande HTTP. Vous pouvez obtenir les valeurs des variables en utilisant la procédure OWA_UTIL.get_cgi_env
.Liste des variables CGI disponibles en PL / 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
Voir aussi: En- tĂȘtes HTTP (OWA_UTIL) et Variables de liaison spĂ©cifiques Ă ORDSExemple 2: accĂšs Ă une table via ORDS
Dans cet exemple, nous considérons l'organisation de l'accÚs à un objet de base de données (à une table) via ORDS.Comme dans l'exemple précédent, nous rendons l'accÚs sans autorisation. Découvrez comment sécuriser l'accÚs aux ressources dans la documentation .Pour rendre un objet de base de données accessible via ORDS, vous devez effectuer une seule étape - la commande ORDS.ENABLE_OBJECT
. AprĂšs cela, l'objet est accessible par un URI de la forme:http://<HOST>:<PORT>/ords/<SchemaAlias>/<ObjectAlias>
.Créer un motif de test
Pour un exemple nous allons créer le tableau "Commandes".Script de création de table:CREATE TABLE T_ORDER
(
id_order NUMBER NOT NULL,
NUM VARCHAR2(32),
buyer_name VARCHAR2(256),
dt_order DATE,
memo VARCHAR2(2000)
);
COMMENT ON TABLE T_ORDER IS '';
COMMENT ON COLUMN T_ORDER.id_order IS ' ';
COMMENT ON COLUMN T_ORDER.num IS ' ';
COMMENT ON COLUMN T_ORDER.buyer_name IS ' ';
COMMENT ON COLUMN T_ORDER.dt_order IS ' ';
COMMENT ON COLUMN T_ORDER.memo IS '';
ALTER TABLE T_ORDER ADD CONSTRAINT PK_T_ORDER PRIMARY KEY (ID_ORDER) USING INDEX;
AccĂšs Ă la table d'ouverture via ORDS
- Dans SQL Developer Invoke le menu contextuel de la table nécessaire, sélectionnez l'option Activer le service le reste ... .

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

- AprÚs avoir effectué ces étapes, la table
T_ORDER
devient disponible via HTTP, l'URI de base pour accéder à la ressource:
http://<server>:<port>/ords/ws_test/t_order
Liste d'inclusion de table:
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
ORDS.ENABLE_OBJECT(p_enabled => TRUE,
p_schema => 'WS_TEST',
p_object => 'T_ORDER',
p_object_type => 'TABLE',
p_object_alias => 't_order',
p_auto_rest_auth => FALSE);
commit;
END;
/
Créer ou modifier un enregistrement
L'accÚs à la table est ouvert - nous vérifions comment vous pouvez créer et modifier des enregistrements dans la table via ORDS.Pour créer un enregistrement, nous exécutons la demande PUT
.Dans la documentation ORDS, la description suivante PUT
est spécifiée dans la description de la méthode :PUT http://<HOST>:<PORT>/ords/<SchemaAlias>/<ObjectAlias>/<KeyValues>
Autrement dit, le champ KeyValues
(clĂ© d'enregistrement) doit ĂȘtre rempli mĂȘme pour un nouvel enregistrement en cours de crĂ©ation. La requĂȘte elle-mĂȘme doit rĂ©pertorier tous les champs de la table (mais le champ clĂ© peut ĂȘtre omis).EnquĂȘtePUT http://<server>:<port>/ords/ws_test/t_order/25 HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: application/json;charset=UTF-8
Content-Length: 157
Host: <server>:<port>
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
{
"num" : "ords-3472634",
"buyer_name" : "Buyer Name",
"dt_order" : "2019-10-25T12:00:00Z",
"memo" : " 1"
}
En rĂ©ponse, nous obtenons tous les champs de l'enregistrement qui vient d'ĂȘtre créé:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Location: http://<server>:<port>/ords/ws_test/t_order/25
ETag: "..."
Transfer-Encoding: chunked
{
"id_order": 25,
"num": "ords-3472634",
"buyer_name": "Buyer Name",
"dt_order": "2019-10-25T12:00:00Z",
"memo": " 1",
"links": [
{
"rel": "self",
"href": "http://<server>:<port>/ords/ws_test/t_order/25"
},
{
"rel": "edit",
"href": "http://<server>:<port>/ords/ws_test/t_order/25"
},
{
"rel": "describedby",
"href": "http://<server>:<port>/ords/ws_test/metadata-catalog/t_order/item"
},
{
"rel": "collection",
"href": "http://<server>:<port>/ords/ws_test/t_order/"
}
]
}
Nous regardons le contenu du tableau - notre nouvel enregistrement est apparu:
Pour changer l'enregistrement, nous appelons la mĂȘme mĂ©thode PUT. Modifiez la note dans notre commande:PUT http://<server>:<port>/ords/ws_test/t_order/25 HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: application/json;charset=UTF-8
Content-Length: 178
Host: <server>:<port>
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
{
"num" : "ords-3472634",
"buyer_name" : "Buyer Name",
"dt_order" : "2019-10-25T12:00:00Z",
"memo" : " 1. "
}
Dans la rĂ©ponse, nous obtenons le mĂȘme JSON avec les paramĂštres de l'enregistrement modifiĂ©. Dans le tableau, nous voyons que la note a Ă©tĂ© mise Ă jour:
Récupération des enregistrements d'une table
Il existe trois modes d'interrogation des données d'une table:- Demande de page:
GET http://<HOST>:<PORT>/ords/<SchemaAlias>/<ObjectAlias>/?offset=<Offset>&limit=<Limit>
- Demande de conditions:
GET http://<HOST>:<PORT>/ords/<SchemaAlias>/<ObjectAlias>/?q=<FilterClause>
- Demande de clé primaire:
GET http://<HOST>:<PORT>/ords/<SchemaAlias>/<ObjectAlias>/<KeyValues>
Pour obtenir tous les enregistrements, vous pouvez exĂ©cuter la requĂȘte sans spĂ©cifier de paramĂštres:GET http://<server>:<port>/ords/ws_test/t_order/
RéponseHTTP/1.1 200 OK
Date: Fri, 25 Oct 2019 15:39:58 GMT
Content-Type: application/json
ETag: "..."
Transfer-Encoding: chunked
{
"items": [ {
"id_order": 25,
"num": "ords-3472634",
"buyer_name": "Buyer Name",
"dt_order": "2019-10-25T12:00:00Z",
"memo": "Ń”ĐâŃĐâčâ ·°Ń°· 1. ·Ń”Đ
âĐ ŃĐŃ”âĄÂ°Đ
”",
"links": [ {
"rel": "self",
"href": "http://<server>:<port>/ords/ws_test/t_order/25"
}]
}],
"hasMore": false,
"limit": 25,
"offset": 0,
"count": 1,
"links": [
{
"rel": "self",
"href": "http://<server>:<port>/ords/ws_test/t_order/"
},
{
"rel": "edit",
"href": "http://<server>:<port>/ords/ws_test/t_order/"
},
{
"rel": "describedby",
"href": "http://<server>:<port>/ords/ws_test/metadata-catalog/t_order/"
},
{
"rel": "first",
"href": "http://<server>:<port>/ords/ws_test/t_order/"
}
]
}
Comment demander Ă Oracle d'ajouter un encodage Ă l'en-tĂȘte Content-Type est une question ouverte.GET http://<server>:<port>/ords/ws_test/t_order/25
RéponseHTTP/1.1 200 OK
Date: Fri, 25 Oct 2019 15:44:35 GMT
Content-Type: application/json
ETag: "..."
Transfer-Encoding: chunked
{
"id_order": 25,
"num": "ords-3472634",
"buyer_name": "Buyer Name",
"dt_order": "2019-10-25T12:00:00Z",
"memo": "Ń”ĐâŃĐâčâ ·°Ń°· 1. ·Ń”Đ
âĐ ŃĐŃ”âĄÂ°Đ
”",
"links": [
{
"rel": "self",
"href": "http://<server>:<port>/ords/ws_test/t_order/25"
},
{
"rel": "edit",
"href": "http://<server>:<port>/ords/ws_test/t_order/25"
},
{
"rel": "describedby",
"href": "http://<server>:<port>/ords/ws_test/metadata-catalog/t_order/item"
},
{
"rel": "collection",
"href": "http://<server>:<port>/ords/ws_test/t_order/"
}
]
}
Supprimer l'enregistrement
Pour supprimer, utilisez la méthode HTTP DELETE
.EnquĂȘte:DELETE http://<server>:<port>/ords/ws_test/t_order/?q={"id_order":25}
La demande dans sa forme originale:DELETE http://<server>:<port>/ords/ws_test/t_order/?q=%7B%22id_order%22%3A25%7D
Réponse:HTTP/1.1 200 OK
Date=Fri, 25 Oct 2019 16:23:39 GMT
Content-Type=application/json
Transfer-Encoding=chunked
{"rowsDeleted":1}
résultats
ORDS est un mĂ©canisme assez flexible et polyvalent pour travailler avec des services Web, qui vous permet de mettre en Ćuvre un REST Ă part entiĂšre. En termes de performances, il est de loin supĂ©rieur Ă Native Oracle WS avec sa lourde analyse XML interne. Pour implĂ©menter un systĂšme trĂšs chargĂ©, cette approche ne convient pas: dans ce cas, une pile technologique diffĂ©rente est nĂ©cessaire - un serveur d'applications distinct, des requĂȘtes de proxy, des bases de donnĂ©es en cluster, etc. Cependant, pour la mise en Ćuvre de systĂšmes avec un nombre relativement faible de requĂȘtes HTTP (jusqu'Ă 10-20 par seconde), ORDS est l'approche optimale en termes de performances et de flexibilitĂ©. ORDS est infĂ©rieur Ă Native Oracle WS uniquement en termes de gĂ©nĂ©ration d'une spĂ©cification de service Web: ce dernier fournit une spĂ©cification entiĂšrement finalisĂ©e (WSDL) qui peut ĂȘtre fournie «telle quelle» aux consommateurs du service. ORDS a Ă©galement la capacitĂ©gĂ©nĂ©rer une description, mais pour l'approche considĂ©rĂ©e dans cet article avec un service entiĂšrement universel (lorsqu'il existe une procĂ©dure de traitement commune pour tous les services), la gĂ©nĂ©ration automatique de la spĂ©cification devient impossible. Oracle ne gĂ©nĂ©rera qu'une spĂ©cification de niveau supĂ©rieur et les piĂšces (modĂšles de donnĂ©es) devront ĂȘtre dĂ©crites manuellement.Approches alternatives
Servlet Java
Cette option de création de services Web dans la méthode de configuration est similaire à Native Oracle WS: elle nécessite également l'utilisation du serveur HTTP intégré d'Oracle, ainsi que des paramÚtres ACL (comme d'ailleurs toutes les autres méthodes). Mais, contrairement à Native Oracle WS, cette option fonctionne avec HTTP pur. Les gestionnaires des demandes dans ce cas sont écrits en Java et ne regarder que le type HTTP demande ( PUT
, GET
, POST
, et ainsi de suite, bien qu'il puisse ĂȘtre fait et un gestionnaire pour tous les types), et la logique de traitement reste entiĂšrement Ă la discrĂ©tion du promoteur. Vous pouvez transfĂ©rer le corps de la demande «tel quel» dans la logique de la base de donnĂ©es, le dĂ©sassembler et le traiter lĂ -bas, vous pouvez laisser une partie de la logique du cĂŽtĂ© du gestionnaire Java et appeler la procĂ©dure souhaitĂ©e Ă partir de la base de donnĂ©es en fonction des donnĂ©es fournies dans la demande.Cette approche de la mise en Ćuvre des services Web est assez universelle et ne nĂ©cessite pas non plus l'installation de composants supplĂ©mentaires. Nous n'avons pas rĂ©ussi Ă l'appliquer uniquement en raison des exigences strictes du service: nous avions besoin d'un service Web qui ne nĂ©cessitait pas d'authentification. Lors de la mise en Ćuvre de cette approche, l'authentification est requise et cette exigence n'a pas pu ĂȘtre contournĂ©e.Voir la documentation Oracle pour plus de dĂ©tails sur cette mĂ©thode .Descripteur d'accĂšs Ă la base de donnĂ©es (servlet PL / SQL)
Cette option est complĂštement similaire Ă la prĂ©cĂ©dente, seule la procĂ©dure stockĂ©e PL / SQL agit comme gestionnaire de requĂȘtes.Exemple d'URL - le nom du package, le nom de la procĂ©dure, les paramĂštres (requĂȘte GET) sont indiquĂ©s:GET http://<server>:<port>/servlet_plsql/pi_test.test_serv?p_path=ppp
Dans le cas d'une requĂȘte POST, les noms des paramĂštres doivent ĂȘtre saisis directement dans le corps de la requĂȘte via le signe «=», ce qui est plutĂŽt gĂȘnant, car le type du contenu de la requĂȘte (ContentType) dans ce cas ne peut ĂȘtre que du texte. Vous pouvez transfĂ©rer une structure xml ou json uniquement sous cette forme:p_proc_param_name=<xml_data>âŠ</xml_data>
Cette version du service Web n'est applicable que dans les cas oĂč nous traitons des demandes trĂšs simples - appels de procĂ©dure avec des types de donnĂ©es simples. La transmission de toute structure complexe Ă plusieurs niveaux dans cette option ne fonctionnera pas.Cette approche est dĂ©crite en dĂ©tail sur le site Internet ORACLE-BASE.Conclusion
La crĂ©ation d'un service Web dans Oracle est une tĂąche assez simple qui ne nĂ©cessite pas d'Ă©crire n'importe quel type de code super complexe. Dans le mĂȘme temps, les dĂ©veloppeurs Oracle intĂšgrent dans leur arsenal un mĂ©canisme assez puissant qui vous permet d'intĂ©grer des systĂšmes hĂ©tĂ©rogĂšnes ou des parties de systĂšmes via HTTP.Dans cet article, nous avons examinĂ© quatre approches pour crĂ©er des services Web.Native Oracle WS est une technologie obsolĂšte qui a nĂ©anmoins ses avantages: WSDL gĂ©nĂ©rĂ© automatiquement, analyse automatique de XML, pas besoin d'installer de logiciel supplĂ©mentaire. Le principal inconvĂ©nient est la faible performance et la limitation des types de donnĂ©es pris en charge.ORDS- Ă mon avis, la façon prĂ©fĂ©rĂ©e de crĂ©er des services Web. Assez flexible et polyvalent. Parmi les inconvĂ©nients de cette mĂ©thode, nous pouvons seulement distinguer qu'elle n'est pas incluse dans le package Oracle standard, c'est-Ă -dire qu'elle nĂ©cessite une installation distincte.Java Servlet est un moyen complĂštement universel qui ne nĂ©cessite pas l'installation de logiciels supplĂ©mentaires. Cependant, tout doit ĂȘtre fait entiĂšrement manuellement, car il n'y a aucune possibilitĂ© de services de gĂ©nĂ©ration automatique.PL / SQL Servlet est l'approche la moins rĂ©ussie. Parmi les avantages, nous pouvons distinguer que dans cette option, nous avons la possibilitĂ© d'appeler des procĂ©dures stockĂ©es via HTTP sans avoir besoin d'installer de logiciel supplĂ©mentaire, ou sans Ă©crire de code supplĂ©mentaire dans d'autres langues: tout le code est Ă©crit uniquement en PL / SQL.Merci Ă tous pour votre attention! J'espĂšre que l'article sera utile Ă ceux qui sont en quelque sorte connectĂ©s aux produits Oracle et sont perplexes face aux problĂšmes d'intĂ©gration intra-systĂšme et intersystĂšmes.