Веб-сервис доступа из хранимой процедуры Oracle

Поскольку вы используете довольно миниатюрный JSON-анализатор com.codename1.io.JSONParser , который анализирует JSON в Map и ничего больше, тогда вы хотите преобразовать Object, которое вы получаете выберите значение для ожидаемого типа и повторите оттуда.

Если объект JSON верхнего уровня является массивом, то создается специальный элемент "root", который вы здесь получаете. Это означает, что структура вашего JSON анализируется следующим образом:

{
    "root": [
        {
            "name": ,
            "stock_status": ,
            "date_created": ,
            "images": 
                {
                    "id": ,
                    "date_*": ,
                    "src": ,
                    "name": ,
                    "alt": 
                }
            ]
        }
    ]
}

Итак, чтобы извлечь src изображения, вы извлекли массив "root" и итерировали по нему. Однако вместо того, чтобы приводить результаты к Map, вы хотите оставить их как Map:

for (const Map element : (List>) result.get("root")) {
    // The "element" object has an "images" value that is a list of objects
    for (const Map image : (List>) element.get("images")) {
        // Save the "src" field of each image
        productImages.add((String) image.get("src"));
    }
}

10
задан rich 18 November 2008 в 15:37
поделиться

2 ответа

Прежде всего, какой веб-сервис Вы называете? Я принимаю или SOAP или REST.

Для веб-сервисов REST UTL_HTTP часто более, чем достаточен, объединен с небольшим количеством XPath в простой МН хранимой процедуре / хранимой процедуре SQL.

Для веб-сервисов SOAP это зависит от того, как сложный Вы нуждаетесь (или хотите) быть. Можно, конечно, использовать XQuery для создания XML-документа, который встречает спецификацию для веб-сервиса, используйте UTL_HTTP, чтобы отправить документ и получить ответ и затем использовать некоторый XPath для парсинга ответа все в МН / SQL. Это - относительно ручное и решение относительно "в лоб", но если Вы говорите о горстке веб-сервисов, оно включает минимум инфраструктуры, и вызовы могут быть столкнуты довольно быстро.

Если Вы ожидаете, что вызовы разовьются со временем, или Вы ожидаете там быть многими процедурами, называя много веб-сервисов, вероятно, имеет смысл инвестировать время во что-то как UTL_DBWS (это не что-то, тем не менее, что Вы обычно получаете работу через пару часов).

13
ответ дан 3 December 2019 в 17:22
поделиться

Довольно просто перенести 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;

Затем Вам просто нужно что-то к POST конверт 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;

Обратите внимание, что я удалил наш блок обработки исключений, поскольку это не особенно относится к примеру.

С этим у Вас может быть любая другая процедура, генерируют необходимое XML для вызова, сервис, для передачи его через вызывают и анализируют возвращаемое значение.

Мы разработали это решение на 9i база данных, таким образом, мы еще не изучили UTL_DBWS. Это работает отлично, все же.

10
ответ дан 3 December 2019 в 17:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: