当前位置:  开发笔记 > 编程语言 > 正文

从Oracle存储过程访问Web服务

如何解决《从Oracle存储过程访问Web服务》经验,为你挑选了2个好方法。

是否有人从Oracle存储过程成功访问过Web服务?如果是这样,它是Java存储过程吗?PL/SQL存储过程?

我有什么理由不尝试从存储过程中访问WS吗?

这是我到目前为止发现的几个参考文献

数据库Web服务

从Java存储过程调用外部Web服务

..只是澄清一下,这是针对SOAP调用的



1> Justin Cave..:

首先,你打电话给什么样的网络服务?我假设SOAP或REST.

对于REST Web服务,UTL_HTTP通常绰绰有余,在简单的PL/SQL存储过程中结合了一点XPath.

对于SOAP Web服务,它取决于您需要(或想要)的复杂程度.您当然可以使用XQuery创建符合Web服务规范的XML文档,使用UTL_HTTP发布文档并获取响应,然后使用一些XPath来解析PL/SQL中的所有响应.这是一个相对手动且相对暴力的解决方案,但是如果你谈论的是少数几个Web服务,那么它涉及的基础设施最少,而且可以很快将这些呼叫结合在一起.

如果您希望调用随着时间的推移而发展,或者您希望有许多过程调用大量的Web服务,那么将时间花在像UTL_DBWS这样的东西上可能是有意义的(但这通常不会在几个小时内工作).


即使我不理解它,我也要投票.

2> kurosch..:

将UTL_HTTP包装在一个便利函数中相当简单:

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;

然后你需要一些东西来发布一个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,
        '' || 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  element
    RETURN v_envelope.extract(
        '/soap:Envelope/soap:Body/*[position() = 1]', 
        'xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"'
    );

END;

请注意,我删除了我们的异常处理块,因为它与示例不是特别相关.

有了它,您可以让任何其他过程生成调用服务所需的XML,通过调用传递它,并解析返回值.

我们在9i数据库上开发了这个解决方案,所以我们还没有研究过UTL_DBWS.但它很棒.

推荐阅读
mobiledu2402851377
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有