Oracle PL/SQL调用APEX_WEB_SERVICE请求ISO-8859-1站点响应乱码问题
解决方案
- 问题根源:
APEX_WEB_SERVICE.MAKE_REST_REQUEST默认会将响应内容按照UTF-8编码转换为数据库字符集(你的库为WE8MSWIN1252),如果目标站点返回的ISO-8859-1编码响应头没有明确标注charset=ISO-8859-1,转换过程就会将é、è这类非UTF-8字符识别为无效字符,替换为¿。你拿到的响应字符串已经是损坏后的结果,后续再调用转码函数也无法恢复原始数据。 - 方案1:直接接收二进制响应自行转码
使用MAKE_REST_REQUEST的BLOB返回重载获取原始二进制数据,再用国际化转换函数手动转码,避免自动转码带来的损坏,示例代码如下:
DECLARE l_response_blob BLOB; l_response VARCHAR2(32767); BEGIN -- 设置请求头 apex_web_service.g_request_headers(1).name := 'Content-Type'; apex_web_service.g_request_headers(1).value := 'text/csv'; apex_web_service.g_request_headers(2).name := 'Accept-Charset'; apex_web_service.g_request_headers(2).value := 'iso-8859-1'; -- 接收二进制响应 l_response_blob := apex_web_service.make_rest_request( p_url => MY_URL || '/download_csv', p_http_method => 'GET' ); -- 手动转码:将ISO-8859-1编码的二进制内容转为数据库字符集的字符串 l_response := UTL_I18N.RAW_TO_CHAR( p_raw => DBMS_LOB.SUBSTR(l_response_blob, DBMS_LOB.GETLENGTH(l_response_blob), 1), p_charset => 'WE8ISO8859P1' ); END; /
- 方案2:指定UTL_HTTP响应编码(适合小数据量场景)
因为APEX_WEB_SERVICE底层调用UTL_HTTP,你可以在发起请求前设置全局响应编码,强制UTL_HTTP按照ISO-8859-1解析响应:
BEGIN UTL_HTTP.SET_RESPONSE_CHARSET('WE8ISO8859P1'); -- 后续正常调用APEX_WEB_SERVICE.MAKE_REST_REQUEST即可 END; /
- 注意:不要使用已废弃的
CONVERT函数做转码,Oracle官方推荐使用UTL_I18N包的相关函数处理字符集转换,兼容性和准确率更高。
内容的提问来源于stack exchange,提问作者Kabulan0lak
相关产品推荐
相关产品推荐

