Как загрузить данные из интернет (utl_http.request)?

Ловец Стрекоз
Дата: 30.05.2006 16:36:04
используется следующая строка

select sys.xmltype.createXML(utl_http.request('http://www.cbr.ru/scripts/XML_daily.asp?date_req=02/03/2005')) from dual;


наличествует две проблемы
1. неверно возвращается русский текст
2. сбой разбора XML

select * from nls_session_parameters
возвращает следующее


NLS_LANGUAGE RUSSIAN
NLS_TERRITORY CIS
NLS_CURRENCY р.
NLS_ISO_CURRENCY CIS
NLS_NUMERIC_CHARACTERS ,
NLS_CALENDAR GREGORIAN
NLS_DATE_FORMAT DD-Mon-RRRR
NLS_DATE_LANGUAGE RUSSIAN
NLS_SORT RUSSIAN
NLS_TIME_FORMAT HH24:MI:SSXFF
NLS_TIMESTAMP_FORMAT DD.MM.RR HH24:MI:SSXFF
NLS_TIME_TZ_FORMAT HH24:MI:SSXFF TZR
NLS_TIMESTAMP_TZ_FORMAT DD.MM.RR HH24:MI:SSXFF TZR
NLS_DUAL_CURRENCY р.
NLS_COMP BINARY
NLS_LENGTH_SEMANTICS BYTE
NLS_NCHAR_CONV_EXCP FALSE
Denis Popov
Дата: 30.05.2006 17:23:58
UTL_HTTP.SET_BODY_CHARSET. В качестве примера код с этой страницы: http://xpoint.ru/know-how/XpW/FormattingSandbox/PodsvetkaSintaksisa?comments
 
function get_clobFromUrl(p_url varchar2, p_charset varchar2 default 'UTF8') return clob is
  req   utl_http.req; 
  resp  utl_http.resp;
  val varchar2(32547);
  a clob;
BEGIN
  dbms_lob.createtemporary(a,true);
  dbms_lob.open(a,dbms_lob.lob_readwrite);
  req := utl_http.begin_request(p_url);
  utl_http.set_body_charset(req, p_charset);
  resp := utl_http.get_response(req);
  LOOP
    a := a||val;
    utl_http.read_text(resp, val, 5000);
  END LOOP;
  utl_http.end_response(resp);
  return a;
EXCEPTION
  WHEN utl_http.end_of_body THEN
    utl_http.end_response(resp);
    return a;
  WHEN others then
    utl_http.end_response(resp);
    raise;
END;

Далее
select get_clobFromUrl('http://www.cbr.ru/scripts/XML_daily.asp?date_req=02/03/2005', 'CL8MSWIN1251') from dual;
vkovalev
Дата: 24.08.2011 17:41:41
поиском набрел на эту тему.
сам тоже пытаюсь вызвать веб сервер.
создал для проверки эту функцию из примера. ситуация токая же, возвращает как и моя функция
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head>body>
<h1>Not Found</h1>
<p>The requested URL /WebService/MilesPlus.asmx was not found on this server.</p>
<hr>
<address>Apache/2.2.3 (CentOS) Server at 10.233.106.144 Port 10856</address>
</body></html>


чего может не хватать для вызова?
Dimitry Sibiryakov
Дата: 24.08.2011 17:46:04

vkovalev
чего может не хватать для вызова?

Наличия на сервера файла /WebService/MilesPlus.asmx.

Posted via ActualForum NNTP Server 1.4

vkovalev
Дата: 24.08.2011 18:07:47
Dimitry Sibiryakov,

в наличии.

через IExplorer доступен. и через вызов из Visual Basic работает
Dimitry Sibiryakov
Дата: 24.08.2011 18:13:28

vkovalev
в наличии.

А вот Апач с тобой не согласен... Покажи URL из IE.

Posted via ActualForum NNTP Server 1.4

publexus
Дата: 24.08.2011 18:17:29
vkovalev
Dimitry Sibiryakov,

в наличии.

через IExplorer доступен. и через вызов из Visual Basic работает

Значит чего то ты напортачил. Покажи кусок кода где ты инициализируешь пакет utl_http и request, а также покажи строку адреса, которую вводишь в IExplorer.
vkovalev
Дата: 24.08.2011 18:50:38
publexus,

с удовольствием)


create or replace
function get_REPORT(p_url varchar2) return clob is
req utl_http.req;
resp utl_http.resp;
val varchar2(32547);
soap_request VARCHAR2 (500);
a VARCHAR2 (500);
BEGIN
soap_request :=
'<?xml version="1.0" encoding="utf-8"?>'
||'<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">'
||'<soap:Body>'
|| '<GetAllMonthReports xmlns="http://milesplus.org/">'
||'<user>"vkovalev"</user>'
||'<password>"Kvass_88"</password>'
||'<month>"201107"</month>'
||'</GetAllMonthReports>'
||'</soap:Body>'
||'</soap:Envelope>';


req := utl_http.begin_request(p_url, 'POST','HTTP/1.1');

utl_http.set_header(req, 'Content-Type', 'text/xml; charset=utf-8');
utl_http.set_header(req, 'Content-Length', length(soap_request));
utl_http.set_header(req, 'SOAPAction', '"http://milesplus.org/GetAllMonthReports"');

utl_http.write_text(req, soap_request);
resp := utl_http.get_response(req);
dbms_output.put_line('resp:--' || resp.status_code);

LOOP
a := a||val;
utl_http.read_text(resp, val);

END LOOP;
utl_http.end_response(resp);
return a;
EXCEPTION
WHEN utl_http.end_of_body THEN
utl_http.end_response(resp);
return a;
WHEN others then
utl_http.end_response(resp);
raise;
END;


адрес http://10.233.106.144:10856/WebService/MilesPlus.asmx
publexus
Дата: 25.08.2011 11:20:40
vkovalev,

Может, конечно, пароли и не стоило сюда копировать, но все же спасибо)))

1. Иногда необходимо (как правило, если на хосте крутится несколько виртуальных сайтов) указывать имя:
utl_http.set_header(req, 'Host', 'www.yourhostname.ru');

2. При определении Content-Length могут быть проблемы, т.к. length считает количество символов, но не байт. Более того данные, в зависимости от настроек, могут предаваться совсем не в той кодировке, в которой тебе хотелось бы. Поэтому текст надо кодировать в двоичный blob с требуемой кодировкой и передавать его (от него же и считать размер). Пример перевода из текстового clob в blob:
	declare
	v_clob clob := null;
	v_blob blob := null;
...
	dbms_lob.createtemporary(v_blob, true, dbms_lob.session);
	dbms_lob.convertToBlob(dest_lob =>  v_blob
						,src_clob => v_clob
						,amount => dbms_lob.lobmaxsize
						,dest_offset => 1
						,src_offset => 1
						,blob_csid => NLS_CHARSET_ID ('UTF8')
						,lang_context => dbms_lob.default_lang_ctx
						,warning => dbms_lob.no_warning
			);
...
	utl_http.set_header(req, 'Content-Length', dbms_lob.getlength(v_blob));
Если размер передаваемых данных большой, то передавать их надо в цикле небольшими пачками, иначе может возникнуть ошибка:
	declare
		l_buf_size	constant	integer	:= 32767;
		l_text		varchar2(32767);
	begin
		for i in 0..floor(length(l_request_blob)/l_buf_size) loop
			UTL_HTTP.write_raw(req, dbms_lob.substr(lob_loc => v_blob, amount => l_buf_size, offset => l_buf_size*i+1));
		end loop;
	end;

Может быть и не все здесь касается твоего случая, но привожу на всякий случай.
И еще раз проверь, соответствует ли url вводимый в explorer и передаваемый функции, включая и номер порта.
vkovalev
Дата: 08.09.2011 20:26:04
publexus,
немного поправил и возвращает положительный код 200 и ответ, только пустой:
<?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body> <GetAllMonthReportsResponse xmlns="http://milesplus.org/">
<GetAllMonthReportsResult />
</GetAllMonthReportsResponse>
</soap:Body></soap:Envelope>


в <GetAllMonthReportsResult /> не возвращается результат.

вылетает на EXCEPTION - ORA-29266:end-of-body reached ((