Use the APEX_WEB_SERVICE API to invoke a Web service and examine the response anywhere you can use PL/SQL in Application Express.
The following are examples of when you might use the APEX_WEB_SERVICE API:
When you want to invoke a Web service by using an On Demand Process using AJAX.
When you want to invoke a Web service as part of an Authentication Scheme.
When you need to pass a large binary parameter to a Web service that is base64 encoded.
When you want to invoke a Web service as part of a validation.
Topics:
There is a procedure and a function to invoke a SOAP style Web service. The procedure stores the response in the collection specified by the parameter p_collection_name. The function returns the results as an XMLTYPE. To retrieve a specific value from the response, you use either the PARSE_RESPONSE function if the result is stored in a collection or the PARSE_XML function if the response is returned as an XMLTYPE. To pass a binary parameter to the Web service as base64 encoded character data, use the function BLOB2CLOBBASE64. Conversely, to transform a response that contains a binary parameter that is base64 encoded use the function CLOBBASE642BLOB.The following is an example of using the BLOB2CLOBBASE64 function to encode a parameter, MAKE_REQUEST procedure to call a Web service, and the PARSE_RESPONSE function to extract a specific value from the response.
declare
l_filename varchar2(255);
l_BLOB BLOB;
l_CLOB CLOB;
l_envelope CLOB;
l_response_msg varchar2(32767);
BEGIN
IF :P1_FILE IS NOT NULL THEN
SELECT filename, BLOB_CONTENT
INTO l_filename, l_BLOB
FROM APEX_APPLICATION_FILES
WHERE name = :P1_FILE;
l_CLOB := apex_web_service.blob2clobbase64(l_BLOB);
l_envelope := q'!<?xml version='1.0' encoding='UTF-8'?>!';
l_envelope := l_envelope '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:chec="http://www.stellent.com/CheckIn/">
<soapenv:Header/>
<soapenv:Body>
<chec:CheckInUniversal>
<chec:dDocName>'||l_filename||'</chec:dDocName>
<chec:dDocTitle>'||l_filename||'</chec:dDocTitle>
<chec:dDocType>Document</chec:dDocType>
<chec:dDocAuthor>GM</chec:dDocAuthor>
<chec:dSecurityGroup>Public</chec:dSecurityGroup>
<chec:dDocAccount></chec:dDocAccount>
<chec:CustomDocMetaData>
<chec:property>
<chec:name></chec:name>
<chec:value></chec:value>
</chec:property>
</chec:CustomDocMetaData>
<chec:primaryFile>
<chec:fileName>'||l_filename'||</chec:fileName>
<chec:fileContent>'||l_CLOB||'</chec:fileContent>
</chec:primaryFile>
<chec:alternateFile>
<chec:fileName></chec:fileName>
<chec:fileContent></chec:fileContent>
</chec:alternateFile>
<chec:extraProps>
<chec:property>
<chec:name></chec:name>
<chec:value></chec:value>
</chec:property>
</chec:extraProps>
</chec:CheckInUniversal>
</soapenv:Body>
</soapenv:Envelope>';
apex_web_service.make_request(
p_url => 'http://127.0.0.1/idc/idcplg',
p_action => 'http://www.stellent.com/CheckIn/',
p_collection_name => 'STELLENT_CHECKIN',
p_envelope => l_envelope,
p_username => 'sysadmin',
p_password => 'welcome1' );
l_response_msg := apex_web_service.parse_response(
p_collection_name=>'STELLENT_CHECKIN',
p_xpath=>'//idc:CheckInUniversalResponse/idc:CheckInUniversalResult/idc:StatusInfo/idc:statusMessage/text()',
p_ns=>'xmlns:idc="http://www.stellent.com/CheckIn/"');
:P1_RES_MSG := l_response_msg;
END IF;
END;
RESTful style Web services use a simpler architecture than SOAP. Typically the input to a RESTful style Web service is a collection of name/value pairs. The response can be an XML document or simply text such as a comma separated response or JSON. The following is an example of MAKE_REST_REQUEST being used in an application process that is callable by AJAX.
declare
l_clob clob;
l_buffer varchar2(32767);
l_amount number;
l_offset number;
begin
l_clob := apex_web_service.make_rest_request(
p_url => 'http://us.music.yahooapis.com/ video/v1/list/published/popular',
p_http_method => 'GET',
p_parm_name => apex_util.string_to_table('appid:format'),
p_parm_value => apex_util.string_to_table(apex_application.g_x01||':'||apex_application.g_x02));
l_amount := 32000;
l_offset := 1;
begin
loop
dbms_lob.read( l_clob, l_amount, l_offset, l_buffer );
htp.p(l_buffer);
l_offset := l_offset + l_amount;
l_amount := 32000;
end loop;
exception
when no_data_found then
null;
end;
end;
When you invoke a Web service using any of the supported methods in Application Express, the g_response_cookies and g_headers globals are populated if the Web service response included any cookies or HTTP headers. You can interrogate these globals and store the information in collections.The following are examples of interrogating the APEX_WEB_SERVICE globals to store cookie and HTTP header responses in collections.
declare
i number;
secure varchar2(1);
begin
apex_collection.create_or_truncate_collection('P31_RESP_COOKIES');
for i in 1.. apex_web_service.g_response_cookies.count loop
IF (apex_web_service.g_response_cookies(i).secure) THEN
secure := 'Y';
ELSE
secure := 'N';
END IF;
apex_collection.add_member(p_collection_name => 'P31_RESP_COOKIES',
p_c001 => apex_web_service.g_response_cookies(i).name,
p_c002 => apex_web_service.g_response_cookies(i).value,
p_c003 => apex_web_service.g_response_cookies(i).domain,
p_c004 => apex_web_service.g_response_cookies(i).expire,
p_c005 => apex_web_service.g_response_cookies(i).path,
p_c006 => secure,
p_c007 => apex_web_service.g_response_cookies(i).version );
end loop;
end;
declare
i number;
begin
apex_collection.create_or_truncate_collection('P31_RESP_HEADERS');
for i in 1.. apex_web_service.g_headers.count loop
apex_collection.add_member(p_collection_name => 'P31_RESP_HEADERS',
p_c001 => apex_web_service.g_headers(i).name,
p_c002 => apex_web_service.g_headers(i).value,
p_c003 => apex_web_service.g_status_code);
end loop;
end;
You set cookies and HTTP headers that should be sent along with a Web service request by populating the globals g_request_cookies and g_request_headers before the process that invokes the Web service.The following examples show populating the globals to send cookies and HTTP headers with a request.
for c1 in (select seq_id, c001, c002, c003, c004, c005, c006, c007
from apex_collections
where collection_name = 'P31_RESP_COOKIES' ) loop
apex_web_service.g_request_cookies(c1.seq_id).name := c1.c001;
apex_web_service.g_request_cookies(c1.seq_id).value := c1.c002;
apex_web_service.g_request_cookies(c1.seq_id).domain := c1.c003;
apex_web_service.g_request_cookies(c1.seq_id).expire := c1.c004;
apex_web_service.g_request_cookies(c1.seq_id).path := c1.c005;
if c1.c006 = 'Y' then
apex_web_service.g_request_cookies(c1.seq_id).secure := true;
else
apex_web_service.g_request_cookies(c1.seq_id).secure := false;
end if;
apex_web_service.g_request_cookies(c1.seq_id).version := c1.c007;
end loop;
for c1 in (select seq_id, c001, c002
from apex_collections
where collection_name = 'P31_RESP_HEADERS' ) loop
apex_web_service.g_request_headers(c1.seq_id).name := c1.c001;
apex_web_service.g_request_headers(c1.seq_id).value := c1.c002;
end loop;