I want to send an UTF8 json string via utl_http to a node.js Server via POST. Sending the string
["Sant Julià de Lòria"]
does arrive as
["Sant Juli� de L�ria"]
The PL/SQL code goes like:
FUNCTION http_post_varchar(
p_url VARCHAR2,
p_request_body VARCHAR2 )
RETURN VARCHAR2
AS
req UTL_HTTP.REQ;
resp UTL_HTTP.RESP;
value VARCHAR2(32767); -- URL to post to
v_url VARCHAR2(200) := p_url;
-- Post Parameters
v_param VARCHAR2(32767) := p_request_body;
v_param_length NUMBER := length(v_param);
BEGIN
req := UTL_HTTP.BEGIN_REQUEST (url=> v_url, method => 'POST');
UTL_HTTP.SET_HEADER (r => req,
name => 'Content-Type',
value => 'application/json;charset=UTF-8');
UTL_HTTP.SET_HEADER (r => req,
name => 'Content-Length',
value => v_param_length);
UTL_HTTP.WRITE_TEXT (r => req,
data => v_param);
resp := UTL_HTTP.GET_RESPONSE(req);
LOOP
UTL_HTTP.READ_LINE(resp, value, TRUE);
END LOOP;
UTL_HTTP.END_RESPONSE(resp);
RETURN 'OK';
EXCEPTION
WHEN UTL_HTTP.END_OF_BODY THEN
UTL_HTTP.END_RESPONSE(resp);
RETURN 'OK';
END http_post_varchar;
You should change your code to:
UTL_HTTP.SET_BODY_CHARSET('UTF-8');
UTL_HTTP.SET_HEADER (r => req,
name => 'Content-Length',
value => LENGTHB(v_param));
UTL_HTTP.WRITE_RAW (r => req,
data => UTL_RAW.CAST_TO_RAW(v_param));
LENGTHB for byte length because of UTF-8. Otherwise the calculated length will be false and you get an error on the target side (unexpected end of input or something).
Same goes for the response body e.g. when you're getting a response from a web service:
UTL_HTTP.SET_BODY_CHARSET(r=> resp, charset=>'UTF-8');
Place this call directly after Get_response.
Sometimes the problem is not with Unicode. You can use the conversion to ASCII code
v_param := REPLACE (ASCIISTR (v_param), '\', '\u');
Related
I am making a stored procedure with 2 seperate HTTP Requests.
The first one to get an Atuthentication Token and the second one that uses the token.
The first Request works without a problem and I get the token back.
The second Request throws the ora-29259 end-of-input reached exception.
They both look exactly the same besides of the URL:
begin
req := utl_http.begin_request(url,'POST',utl_http.http_version_1_1);
utl_http.set_header(req, 'Authorization', Token/Credentials);
utl_http.set_header(req, 'Content-Type', 'application/json');
utl_http.set_header(req, 'Content-Length', length(content));
utl_http.write_text(req, content);
res := utl_http.get_response(req);
loop
utl_http.read_text(res, buffer);
dbms_output.put_line(buffer);
end loop;
utl_http.end_response(res);
exception
when utl_http.end_of_body then
utl_http.end_response(res);
end;
I have found this from nearly 3 years ago which suggests updating the database.
I am using Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production, is this the issue? I can't find any answer to this googling myself.
The first Website uses TLS 1.2 while the second one uses TLS 1.3, is my Oracle Version too old?
Please provide a sample of your code for a more detailed answer.
But looking at the link you provided, I can already see something missing in the code, which is the exception for utl_http.end_of_body.
This is an example of my code, I used somewhere else:
begin
req := utl_http.begin_request(url,'POST',utl_http.http_version_1_1);
utl_http.set_header(req, 'Content-Type', 'application/xml;charset=UTF-8');
utl_http.set_header(req, 'Content-Length', length(content));
utl_http.write_text(req, content);
res := utl_http.get_response(req);
loop
utl_http.read_text(res, buffer);
dbms_output.put_line(buffer);
end loop;
utl_http.end_response(res);
exception
when utl_http.end_of_body then
utl_http.end_response(res);
end;
I'm trying to send some text using utl_http. The Text I'm sending includes special characters
Declare
HttpRequest utl_http.req;
HttpResponse utl_http.resp;
ResponseText clob;
URL varchar2(500) := 'someurl';
PostPrameters varchar2(30000);
begin
PostPrameters := 'From=SenderName&To=+336...&Body=très cool';
PostPrameters := utl_url.escape(PostPrameters);
URL := utl_url.escape(URL);
HttpRequest := utl_http.begin_request(URL, 'POST', 'HTTP/1.1');
utl_http.set_authentication(HttpRequest, TwilioUserName, TwilioPassword);
utl_http.set_header(HttpRequest,'Content-Type','application/x-www-form-urlencoded;');
utl_http.set_header(HttpRequest, 'Content-Length',length(PostPrameters));
utl_http.write_text(HttpRequest, PostPrameters);
HttpResponse := utl_http.get_response(HttpRequest);
utl_http.read_text(HttpResponse,ResponseText);
utl_http.end_response(HttpResponse);
end;
The body of the text I'm sending should be "très cool"
When sending the request, it's received as "tr�s cool"
I tried to add UTL_HTTP.SET_BODY_CHARSET('UTF-8'); but it's not working.
Can anyone help please ?
Thanks.
I have the following cURL request that I want to make in PL/SQL :
curl -i
-H « Authorization: AUTH xxxx:1539335594582:1:HMAC »
-X GET http://example.com/api/accounts
I tried the following code. It's not working (I'm getting a server error : Your browser sent a request that we could not understand.) and I'm not sure if I'm doing it correctly in PL/SQL :
URL varchar2(250);
Header varchar2(32000);
Response varchar2(32000);
URL := 'http://example.com/api/accounts';
Header := 'Authorization: AUTH xxxx:1539335594582:1:HMAC';
Response := apex_web_service.make_rest_request(p_url => URL || '?' || Header, p_http_method => 'GET');
can any one help please ?
Thanks
Cheers,
HTTP headers cannot be concatenated into the URL like that. You need to set the headers before calling make_rest_request, e.g.
declare
URL varchar2(250);
Response varchar2(32000);
begin
URL := 'http://example.com/api/accounts';
apex_web_service.g_request_headers.delete();
apex_web_service.g_request_headers(1).name := 'Authorization';
apex_web_service.g_request_headers(1).value := 'AUTH xxxx:1539335594582:1:HMAC';
Response := apex_web_service.make_rest_request(p_url => URL, p_http_method => 'GET');
end;
I have to get the response headers of my "apex_web_service.make_rest_request" request.
I know that it was possible with the "UTL_HTTP" package, as documented here: https://docs.oracle.com/database/121/ARPLS/u_http.htm#BHAHDHHB
But how can I do this with "apex_web_service"? Is it even possible, as I can't find it in this documentation? http://docs.oracle.com/database/121/AEAPI/apex_web_service.htm#AEAPI537
Thanks in advance for your answer(s)!
Ok I found it now. The answer can be found here: http://docs.oracle.com/database/121/AEAPI/apex_web_service.htm#AEAPI1933
There is no such thing as a "get_Header()" or something like that. You set your headers and send the request (here example code):
--Set Request Headers
apex_web_service.g_request_headers(1).name := 'Authorization';
apex_web_service.g_request_headers(1).value := '[MY API TOKEN]';
apex_web_service.g_request_headers(2).name := 'Content-Type';
apex_web_service.g_request_headers(2).value := 'application/json';
apex_web_service.g_request_headers(3).name := 'Content-Length';
apex_web_service.g_request_headers(3).value := '[CONTENT LENGTH IN BYTES OF REQUEST BODY]';
l_lcResult := apex_web_service.make_rest_request(p_url => 'MY API URL'
,p_http_method => 'POST'
,p_body => 'REQUEST BODY IN JSON FORMAT');
After the request the headers "change" automatically to the response headers. You can get the response headers as followed:
for i in 1.. apex_web_service.g_headers.count loop
l_vcHeaderName := apex_web_service.g_headers(i).name;
l_vcHeaderValue := apex_web_service.g_headers(i).value;
end loop;
If you are searching for a specific response header (like me), you can use this:
--Here we search for the header-field called 'Location'
for i in 1.. apex_web_service.g_headers.count loop
l_vcHeaderName := apex_web_service.g_headers(i).name;
l_vcHeaderValue := apex_web_service.g_headers(i).value;
exit when l_vcHeaderName = 'Location';
end loop;
dbms_output.put_line('Name: ' || l_vcHeaderName);
dbms_output.put_line('Value: ' || l_vcHeaderValue);
If you want the HTTP response code , use:
apex_web_service.g_status_code
I have tried the following way to make the http call :
v_doc_fin clob;
if v_doc_fin is not null then
DBMS_OUTPUT.PUT_LINE (v_doc_fin);
req := utl_http.begin_request(url, 'POST',' HTTP/1.1');
utl_http.set_header(req, 'user-agent', 'mozilla/4.0');
utl_http.set_header(req, 'content-type', 'application/json');
utl_http.set_header(req, 'Content-Length', length(v_doc_fin));
utl_http.write_text(req, v_doc_fin);
res := utl_http.get_response(req);
end if;
I tried using the WRITE_RAW and write_text to make the HTTP request, but neither helped.
UTL_HTTP.write_text (req, v_doc_fin) ;
UTL_HTTP.WRITE_RAW (r => req, data => UTL_RAW.CAST_TO_RAW(v_doc_fin));
I also tried breaking the request body in chunks, but it didn't help either.
The request within 30000 chars limits are working fine, but when they exceed that limit it fails.
Please suggest or advice on the way to send this request body with such large amount of data in Oracle 12c.
If you have Apex installed in the database maybe using apex_web_service.make_rest_request is an option for you.
It sends and receives clob data.
https://docs.oracle.com/database/121/AEAPI/apex_web_service.htm#AEAPI537
Example
l_result_clob := apex_web_service.make_rest_request(p_url => my_url
,p_http_method => 'POST'
,p_body => l_content_clob);