UTF-8字符在HTTP响应pl / sql中被破坏

时间:2014-12-09 11:26:26

标签: rest http utf-8 plsql oracle11g

我使用以下代码读取从Mongo DB到Oracle表的HTTP响应。源(json-like)的某些部分在中文中被收到损坏。行DBMS_OUTPUT.PUT_LINE(buf);显示这些已损坏的值。

FUNCTION FN_READ_CONTACTS_MOB (p_id in number) RETURN NUMBER
IS
OracleBatchNumber number := p_id;
buf NVARCHAR2(32767);
  l_param_list     VARCHAR2(512);

  l_http_request   UTL_HTTP.req;
  l_http_response  UTL_HTTP.resp;

  l_response_text CLOB;


BEGIN
 DBMS_OUTPUT.ENABLE(1000000);
  -- service's input parameters
UTL_HTTP.SET_WALLET('file:C:/app/', 'manager1');
  -- preparing Request...
  l_http_request := UTL_HTTP.begin_request('https://api.appery.io/rest/1/db/collections/Outlet_Details?where=%7B%22%24and%22%3A%5B%7B%22Oracle_Flag%22%3A+%22Y%22%7D%2C+%7B%22OracleBatchNo%22%3A+%22'||OracleBatchNumber||'%22%7D%5D%7D'
                                          , 'GET'
                                          , 'HTTP/1.1');




  -- ...set header's attributes
  UTL_HTTP.set_header(l_http_request, 'X-Appery-Database-Id', '53f2dac5e4b02cca64021dbe');
  --UTL_HTTP.set_header(l_http_request, 'Content-Length', LENGTH(l_param_list));

  -- ...set input parameters
 -- UTL_HTTP.write_text(l_http_request, l_param_list);

  -- get Response and obtain received value
  l_http_response := UTL_HTTP.get_response(l_http_request);

--using a loop read teh response, as UTL_HTTP.read_text hat returns the result as a VARCHAR2 (max 32767) (you have an implicit conversion here).
    BEGIN
      LOOP
        UTL_HTTP.read_text(l_http_response, buf);
        DBMS_OUTPUT.PUT_LINE(buf);
        l_response_text := l_response_text || buf;
      END LOOP;
    EXCEPTION
    WHEN UTL_HTTP.end_of_body THEN
      NULL;
    END;

 .....

当我运行以下内容时:

select value from nls_database_parameters where parameter='NLS_CHARACTERSET';

然后返回:AL32UTF8。

并不意味着我的数据库配置为UTF-8?或者还有其他事情需要检查这个目的吗?

2 个答案:

答案 0 :(得分:1)

聚会有点晚了...解决方案是使用 dbms_lob “嵌套”数据,以便 Oracle 可以正确地将其转换回来:

DECLARE
    l_clob            CLOB;
    l_http_request    utl_http.req;
    l_http_response   utl_http.resp;
    l_text            VARCHAR2(32767);
BEGIN
    dbms_lob.createtemporary(l_clob, false);
    /* ... */

    BEGIN
        LOOP
            utl_http.read_text(l_http_response, l_text, 32766);
            dbms_lob.writeappend(l_clob, length(l_text), l_text);
        END LOOP;
    EXCEPTION
        WHEN utl_http.end_of_body THEN
            utl_http.end_response(l_http_response);
    END;

    /* l_clob contains your data now correctly encoded */

    dbms_lob.freetemporary(l_blob);
EXCEPTION
    WHEN OTHERS THEN
        utl_http.end_response(l_http_response);
        dbms_lob.freetemporary(l_blob);
        RAISE;
END;
/

希望这可以帮助其他人。来自Donald Burleson's article的想法。

答案 1 :(得分:0)

尝试将persistant_conn_support设置为true,以便在超时之前收到完整的响应。

utl_http.set_persistent_conn_support(l_http_request,true);  -- keep connection open