【问题标题】:PL/SQL: UTL_HTTP POST with UTF8 string results in broken charactersPL/SQL:带有 UTF8 字符串的 UTL_HTTP POST 导致字符损坏
【发布时间】:2014-03-18 02:02:45
【问题描述】:

我想通过 utl_http 将 UTF8 json 字符串通过 POST 发送到 node.js 服务器。发送字符串

["Sant Julià de Lòria"]

确实到达

["Sant Juli� de L�ria"]

PL/SQL 代码如下:

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;

【问题讨论】:

  • 你的数据库字符集是什么?你的会话 nls_lang 字符集是什么?
  • 字符集:AL32UTF8 NLS_CHARACTERSET:德语
  • 您确定将响应读取为 UTF8 字符串吗?看起来好像您尝试使用 8 位字符集读取 UTF8 字符串 (ò => �)

标签: oracle http post utf-8 plsql


【解决方案1】:

有时问题不在于 Unicode。您可以使用转换为 ASCII 码

 v_param := REPLACE (ASCIISTR (v_param), '\', '\u');

【讨论】:

    【解决方案2】:

    响应正文也是如此,例如当您收到来自网络服务的响应时:

    UTL_HTTP.SET_BODY_CHARSET(r=> resp, charset=>'UTF-8');
    

    Get_response之后直接调用。

    【讨论】:

      【解决方案3】:

      您应该将代码更改为:

      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 表示字节长度,因为 UTF-8。否则计算的长度将是错误的,并且您会在目标端收到错误(输入的意外结束或其他东西)。

      【讨论】:

      • 我通过另外添加“utl_http.set_body_charset('UTF-8');”使它终于工作了注意:此设置一旦执行,对整个会话有效,即使您删除它进行测试,它仍然有效。
      • 将行添加到解决方案中
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-01
      相关资源
      最近更新 更多