2009-07-27 11 views
2

Hintergrund: Wir haben einen Webservice, der unter axis2 auf einem Tomcat läuft. Wir möchten, dass unsere Oracle-Datenbank (10g Enterprise Edition, Version 10.2.0.1.0) unseren Webservice aufruft, wenn eine neue Zeile in eine unserer Tabellen eingegeben wird. Wir haben herausgefunden, dass wir einen Trigger verwenden können, um eine Java Stored Procedure (JSP) oder PL/SQL und das Dienstprogramm UTL_DBWS aufzurufen. Beides funktioniert jedoch nicht für uns. Das Verwenden des Webdienstes von einer eigenständigen Java-Klasse mit der Axis-Implementierung javax.xml.rpc oder der Oracle-Implementierung funktioniert auch außerhalb der db.Webservice mit UTL_DBWS konsumieren

UTL_DBWS Versuch:

entpackten Inhalt dbws-callout-utility-10131.zip in C: \ oracle \ product \ 10.2.0 \ DB_5 \ sqlj \ lib, die von http://www.oracle.com/technology/sample_code/tech/java/jsp/dbwebservices.html nach unten

gezogen wurde

lief loadjava Befehl

loadjava -u <USER>/<PASSWORD>@<MACHINE>:1521:<INSTANCE> -r -v -f -genmissing -s -grant public C:\oracle\product\10.2.0\db_5\sqlj\lib\dbwsclientws.jar C:\oracle\product\10.2.0\db_5\sqlj\lib\dbwsclientdb102.jar 

hinzugefügt eine Reihe von Berechtigungen

execute dbms_java.grant_permission('<<user>>', 'SYS:java.lang.RuntimePermission', 'getClassLoader', '') 
    execute dbms_java.grant_permission('<<user>>', 'SYS:oracle.aurora.security.JServerPermission', 'Verifier', ''); 
    execute dbms_java.grant_permission('<<user>>', 'SYS:java.lang.RuntimePermission', 'accessClassInPackage.sun.util.calendar', '') ; 
    execute dbms_java.grant_permission('<<user>>', 'SYS:java.net.SocketPermission', '<<machineName>>', 'resolve'); 
    execute dbms_java.grant_permission('<<user>>', 'SYS:java.net.SocketPermission', '<<machineIP>>', 'connect,resolve'); 
    execute dbms_java.grant_permission('<<user>>', 'SYS:java.lang.RuntimePermission', 'createClassLoader', ''); 

Unsere PL/SQL:

FUNCTION wsproxy_send_request 
return varchar2 
as 
l_service   SYS.UTL_DBWS.service; 
l_call    SYS.UTL_DBWS.call; 
l_result    ANYDATA; 
l_wsdl_url   VARCHAR2(32767); 
l_namespace   VARCHAR2(32767); 
l_service_qname  SYS.UTL_DBWS.qname; 
l_port_qname   SYS.UTL_DBWS.qname; 
l_operation_qname SYS.UTL_DBWS.qname; 
l_input_params  SYS.UTL_DBWS.anydata_list; 
boolean_type_qname SYS.UTL_DBWS.QNAME; 

begin 

l_wsdl_url := 'http://<<host>>/axis2/services/<<serviceName>>?wsdl'; 
l_namespace := 'http://<<namespace>>'; 
l_service_qname := SYS.UTL_DBWS.to_qname(l_namespace, '<<serviceName>>'); 
l_port_qname := SYS.UTL_DBWS.to_qname(l_namespace, '<<myendpoint>>'); 
l_operation_qname := SYS.UTL_DBWS.to_qname(l_namespace, 'send'); 

l_service := SYS.UTL_DBWS.create_service (wsdl_document_location => URIFACTORY.getURI(l_wsdl_url), service_name => l_service_qname); 
l_call := SYS.UTL_DBWS.create_call (service_handle => l_service, port_name => l_port_qname, operation_name => l_operation_qname); 

SYS.UTL_DBWS.SET_PROPERTY(l_call, 'OPERATION_STYLE', 'rpc'); 

l_input_params(0) := ANYDATA.ConvertNumber(1); 
l_input_params(1) := ANYDATA.ConvertNumber(24387236726); 
l_input_params(2) := ANYDATA.ConvertVarchar2('CTE'); 
l_input_params(3) := ANYDATA.ConvertVarchar2('STORE_RECORD_LOCATOR'); 
l_input_params(4) := ANYDATA.ConvertVarchar2('a'); 

boolean_type_qname := sys.utl_dbws.to_qname('http://www.w3.org/2001/XMLSchema', 'boolean'); 
sys.utl_dbws.set_return_type(l_call, boolean_type_qname); 

l_result := SYS.UTL_DBWS.invoke (call_handle => l_call, input_params => l_input_params); 

SYS.UTL_DBWS.release_call (call_handle => l_call); 
SYS.UTL_DBWS.release_service(service_handle => l_service); 

RETURN ANYDATA.AccessVarchar2(l_result); 
END; 

Wenn wir ausführen:

select wsproxy_send_request from dual; 

erhalten wir:

Error: ORA-29532: Java call terminated by uncaught Java exception: java.lang.ArrayIndexOutOfBoundsException 
ORA-06512: at "SYS.UTL_DBWS", line 568 
ORA-06512: at "SYS.UTL_DBWS", line 492 
ORA-06512: at "SYS.UTL_DBWS", line 380 
ORA-06512: at "WSPROXY.WSPROXY_SEND_REQUEST", line 37 

SQLState: 99999 
ErrorCode: 29532 
Position: 37 

(Position 37 ist die invoke Aufruf)

+0

Bemerkt diese Frage, nachdem ich http://stackoverflow.com/questions/37586/consuming-web-services-from-oracle-pl-sql gefragt Wir können die UTL_HTTP versuchen und sehen, ob das funktioniert. – Josh

+0

Ich habe festgestellt, dass, wenn ich alle Parameter mit Ausnahme der ersten, die ein ungültiger Aufruf für unseren Webservice ist, bekomme ich eine weitere Ausnahme ORA-29532: Java-Aufruf durch nicht abgefangene Java-Ausnahme beendet: javax.xml. rpc.soap.SOAPFaultException: unbekannt ORA-06512: bei "SYS.UTL_DBWS", Zeile 388 ORA-06512: bei "SYS.UTL_DBWS", Zeile 385 ORA-06512: bei "WSPROXY.WSPROXY_SEND_REQUEST ", Zeile 41 aber die coole Sache ist ..., dass dies erzeugt wird, weil Axis die Anfrage empfängt und balking, weil es nicht die richtigen Parameter enthält. – Josh

Antwort

2

Der Trick bestand darin, den Parameter-Typen/Namen hinzufügen ... Ich habe nicht die UTL_DBWS.add_parameter Methode überall dokumentiert gefunden, aber ich habe es die Existenz ahnte von da Sie das gleiche in einem Java zu tun haben Implementierung.

Wie auch immer, hier ist was ich hinzugefügt

string_type_qname := SYS.UTL_DBWS.to_qname('http://www.w3.org/2001/XMLSchema', 'string'); 
long_type_qname := SYS.UTL_DBWS.to_qname('http://www.w3.org/2001/XMLSchema', 'long'); 

SYS.UTL_DBWS.add_parameter(l_call, 'args0', long_type_qname, 'ParameterMode.IN'); 
SYS.UTL_DBWS.add_parameter(l_call, 'args1', long_type_qname, 'ParameterMode.IN'); 
SYS.UTL_DBWS.add_parameter(l_call, 'args2', string_type_qname, 'ParameterMode.IN'); 
SYS.UTL_DBWS.add_parameter(l_call, 'args3', string_type_qname, 'ParameterMode.IN'); 
SYS.UTL_DBWS.add_parameter(l_call, 'args4', string_type_qname, 'ParameterMode.IN'); 

So das Ganze ist jetzt:

CREATE OR REPLACE 
FUNCTION wsproxy_send_request 
return varchar2 
as 
l_service    SYS.UTL_DBWS.service; 
l_call    SYS.UTL_DBWS.call; 
l_result    ANYDATA; 
l_wsdl_url    VARCHAR2(32767); 
l_namespace    VARCHAR2(32767); 
l_service_qname   SYS.UTL_DBWS.qname; 
l_port_qname   SYS.UTL_DBWS.qname; 
l_operation_qname  SYS.UTL_DBWS.qname; 
l_input_params   SYS.UTL_DBWS.ANYDATA_LIST; 
boolean_type_qname  SYS.UTL_DBWS.QNAME; 
string_type_qname  SYS.UTL_DBWS.QNAME; 
long_type_qname   SYS.UTL_DBWS.QNAME; 

begin 

l_wsdl_url := 'http://<<host>>/axis2/services/<<serviceName>>?wsdl'; 
l_namespace := 'http://<<namespace>>'; 
l_service_qname := SYS.UTL_DBWS.to_qname(l_namespace, '<<serviceName>>'); 
l_port_qname := SYS.UTL_DBWS.to_qname(l_namespace, '<<endPoint>>'); 
l_operation_qname := SYS.UTL_DBWS.to_qname(l_namespace, 'send'); 

l_service := SYS.UTL_DBWS.create_service (URIFACTORY.getURI(l_wsdl_url), l_service_qname); 
l_call := SYS.UTL_DBWS.create_call (l_service, l_port_qname, l_operation_qname); 

boolean_type_qname := SYS.UTL_DBWS.to_qname('http://www.w3.org/2001/XMLSchema', 'boolean'); 
string_type_qname := SYS.UTL_DBWS.to_qname('http://www.w3.org/2001/XMLSchema', 'string'); 
long_type_qname := SYS.UTL_DBWS.to_qname('http://www.w3.org/2001/XMLSchema', 'long'); 

SYS.UTL_DBWS.add_parameter(l_call, 'args0', long_type_qname, 'ParameterMode.IN'); 
SYS.UTL_DBWS.add_parameter(l_call, 'args1', long_type_qname, 'ParameterMode.IN'); 
SYS.UTL_DBWS.add_parameter(l_call, 'args2', string_type_qname, 'ParameterMode.IN'); 
SYS.UTL_DBWS.add_parameter(l_call, 'args3', string_type_qname, 'ParameterMode.IN'); 
SYS.UTL_DBWS.add_parameter(l_call, 'args4', string_type_qname, 'ParameterMode.IN'); 

SYS.UTL_DBWS.SET_PROPERTY(l_call, 'SOAPACTION_USE', 'TRUE'); 
SYS.UTL_DBWS.SET_PROPERTY(l_call, 'SOAPACTION_URI', ''); 
SYS.UTL_DBWS.SET_PROPERTY(l_call, 'ENCODINGSTYLE_URI', ''); 
SYS.UTL_DBWS.SET_PROPERTY(l_call, 'OPERATION_STYLE', 'rpc'); 

l_input_params(0) := ANYDATA.ConvertNumber(1); 
l_input_params(1) := ANYDATA.ConvertNumber(24387236726); 
l_input_params(2) := ANYDATA.ConvertVarchar2('CTE'); 
l_input_params(3) := ANYDATA.ConvertVarchar2('STORE_RECORD_LOCATOR'); 
l_input_params(4) := ANYDATA.ConvertVarchar2('a'); 

sys.utl_dbws.set_return_type(l_call, boolean_type_qname); 

l_result := SYS.UTL_DBWS.invoke(l_call, l_input_params); 

SYS.UTL_DBWS.release_call (l_call); 
SYS.UTL_DBWS.release_service(l_service); 

RETURN ANYDATA.AccessVarchar2(l_result); 
END; 
/

ich dies schließlich sah nach mehr Aufmerksamkeit auf die in den Oracle-Foren gepostet Führung zahlen http://forums.oracle.com/forums/thread.jspa?threadID=633268&tstart=0

Ich bekomme jetzt null für meine Antwort, aber das Parameterproblem wurde gelöst.

+0

So war die Antwort nicht null, aber das AccessVarcar2 wusste nicht, wie man die boolesche Antwort zu einem varchar2 umwandelt. Nachdem der Rückgabetyp zu einer Schnur eingestellt wurde, funktionierte es : sys.utl_dbws.set_return_type (l_call, string_type_qname); – Josh

0

Ich habe nicht verwendet dieses Paket noch, aber normalerweise sind die Arrays in Oracle von 1 bis N nummeriert. Können Sie die Zeilen 28-32 durch ersetzen:

l_input_params(1) := ANYDATA.ConvertNumber(1); 
l_input_params(2) := ANYDATA.ConvertNumber(24387236726); 
l_input_params(3) := ANYDATA.ConvertVarchar2('CTE'); 
l_input_params(4) := ANYDATA.ConvertVarchar2('STORE_RECORD_LOCATOR'); 
l_input_params(5) := ANYDATA.ConvertVarchar2('a'); 
+0

Danke für die Antwort, das ist eigentlich eines der Dinge, die wir tun dachte auch, aber wir erhalten die gleiche Antwort beginnend mit 0 oder 1. – Josh

Verwandte Themen