2008-11-18 15 views
10

Czy jest ktoś, kto pomyślnie uzyskał dostęp do usługi sieci Web z procedury składowanej Oracle? Jeśli tak, czy była to procedura przechowywana w języku Java? Procedura składowana PL/SQL?Dostęp do usługi WWW z procedury składowanej Oracle

Czy jest jakiś powód, dla którego nie powinienem próbować uzyskać dostęp do WS z przechowywanego proc?

Oto kilka bibl które znalazłem tak daleko

..Just do wyjaśnienia, to dla połączeń

Odpowiedz

13

pierwsze SOAP , jakiego rodzaju usługi internetowe dzwonisz? Zakładam SOAP lub REST.

Dla usług internetowych REST, UTL_HTTP jest często bardziej niż wystarczający, w połączeniu z odrobiną XPath w prostej procedurze przechowywanej PL/SQL.

W przypadku usług sieciowych SOAP zależy to od tego, jak wyrafinowane będą potrzeby (lub potrzeby). Z pewnością możesz użyć XQuery do stworzenia dokumentu XML, który spełnia specyfikację dla usługi internetowej, użyć UTL_HTTP, aby opublikować dokument i uzyskać odpowiedź, a następnie użyć XPath do przeanalizowania odpowiedzi wszystkich w PL/SQL. Jest to stosunkowo ręczne i stosunkowo brutalne rozwiązanie, ale jeśli mówimy o kilku usługach internetowych, wymaga to minimalnej infrastruktury, a połączenia mogą zostać szybko zerwane.

Jeśli spodziewasz się, że połączenia będą ewoluować w miarę upływu czasu lub spodziewana liczba procedur wywołujących wiele usług internetowych, prawdopodobnie warto zainwestować czas w coś podobnego do UTL_DBWS (to jednak nie jest coś takiego, że zazwyczaj pracujesz za kilka godzin).

+3

Mam zamiar zagłosować, chociaż nie rozumiem żadnego z nich. –

+1

Jednym wielkim powodem, dla którego nie należy wywoływać usług z procedur przechowywanych, jest prawdopodobieństwo, że krótka transakcja będzie trwać bardzo długo. Używaj ostrożnie! –

10

Jest to dość proste, aby owinąć UTL_HTTP w funkcji Wygoda:

FUNCTION post 
(
    p_url  IN VARCHAR2, 
    p_data IN CLOB, 
    p_timeout IN BINARY_INTEGER DEFAULT 60 
) 
    RETURN CLOB 
IS 
    -- 
    v_request utl_http.req; 
    v_response utl_http.resp; 
    v_buffer CLOB; 
    v_chunk VARCHAR2(4000); 
    v_length NUMBER; 
    v_index NUMBER; 
BEGIN 

    v_index := 1; 
    v_length := nvl(length(p_data), 0); 

    -- configure HTTP 
    utl_http.set_response_error_check(enable => FALSE); 
    utl_http.set_detailed_excp_support(enable => FALSE); 
    utl_http.set_transfer_timeout(p_timeout); 

    -- send request 
    v_request := utl_http.begin_request(p_url, 'POST','HTTP/1.0'); 
    utl_http.set_header(v_request, 'Content-Type', 'text/xml'); 
    utl_http.set_header(v_request, 'Content-Length', v_length); 
    WHILE v_index <= v_length LOOP 
     utl_http.write_text(v_request, substr(p_data, v_index, 4000)); 
     v_index := v_index + 4000; 
    END LOOP; 

    -- check HTTP status code for error 
    IF v_response.status_code <> utl_http.http_ok THEN 
     raise_application_error(
      cn_http_error, 
      v_response.status_code || ' - ' || v_response.reason_phrase 
     ); 
    END IF; 

    -- get response 
    dbms_lob.createtemporary(v_buffer, FALSE); 
    v_response := utl_http.get_response(v_request); 
    BEGIN 
     LOOP 
      utl_http.read_text(v_response, v_chunk, 4000); 
      dbms_lob.writeappend(v_buffer, length(v_chunk), v_chunk); 
     END LOOP; 
    EXCEPTION 
     WHEN utl_http.end_of_body THEN NULL; 
    END; 
    utl_http.end_response(v_response); 

    RETURN v_buffer; 

END; 

Wtedy po prostu trzeba coś aby umieścić koperty SOAP:

FUNCTION invoke 
(
    p_url IN VARCHAR2, 
    p_method IN XMLTYPE, 
    p_timeout IN NUMBER := 60 
) 
    RETURN XMLTYPE 
IS 
    -- calls the given SOAP service 
    cn_procedure_name CONSTANT VARCHAR2(30) := 'invoke'; 
    -- 
    v_envelope XMLTYPE; 
    v_response CLOB; 
    v_fault XMLTYPE; 
    v_sqlerrm VARCHAR2(2000); 
BEGIN 

    -- wrap method in SOAP envelope 
    SELECT 
     XMLElement(
      "soap:Envelope", 
      XMLAttributes(
       'http://schemas.xmlsoap.org/soap/envelope/' AS "xmlns:soap" 
      ), 
      XMLElement(
       "soap:Body", 
       p_method 
      ) 
     ) 
    INTO 
     v_envelope 
    FROM 
     dual; 

    -- POST request 
    v_response := post(
     p_url, 
     '<?xml version="1.0" encoding="ISO-8859-1"?>' || chr(10) || v_envelope.getClobVal(), 
     p_timeout 
    ); 
    IF v_response IS NULL THEN 
     RAISE null_response; 
    END IF; 

    -- parse response 
    BEGIN 
     v_envelope := XMLType(v_response); 
    EXCEPTION 
     WHEN OTHERS THEN 
      v_sqlerrm := SQLERRM; 
      RAISE xml_parse_error; 
    END; 

    -- check for a fault 
    v_fault := v_envelope.extract( 
     '/soap:Envelope/soap:Body/soap:Fault', 
     'xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"' 
    ); 
    IF v_fault IS NOT NULL THEN 
     v_sqlerrm := v_fault.extract('.//faultstring/text()').getStringVal(); 
     RAISE soap_fault; 
    END IF; 

    -- the actual response is the child of the <soap:Body /> element 
    RETURN v_envelope.extract(
     '/soap:Envelope/soap:Body/*[position() = 1]', 
     'xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"' 
    ); 

END; 

pamiętać, że usunięte z naszego bloku obsługi wyjątków, jak to nie dotyczy szczególnie przykładu.

Dzięki temu można uzyskać dowolną inną procedurę generowania pliku XML niezbędnego do wywołania usługi, przekazania go przez wywołanie i przeanalizowania wartości zwracanej.

Rozwinęliśmy to rozwiązanie w bazie danych 9i, więc jeszcze nie zajrzeliśmy do UTL_DBWS. Działa to jednak świetnie.

Powiązane problemy