Oracle UTL_HTTP非200状态下gzip响应无法自动解压问题求助
Oracle UTL_HTTP非200状态码下gzip响应未自动解压的解决方法
问题原因
Oracle UTL_HTTP组件默认仅对200系列状态码的响应自动处理gzip解压,当接口返回非200状态码(如400、500等)时,即使响应头包含Content-Encoding: gzip,UTL_HTTP也不会自动解压,直接返回原始的gzip二进制数据(表现为十六进制起始为1F8B)。
解决方案
手动检查响应头的编码类型,对gzip编码的原始数据调用UTL_COMPRESS.GUNZIP函数进行解压,步骤如下:
- 获取响应对象后,先读取响应状态码和
Content-Encoding头 - 若
Content-Encoding为gzip,读取原始RAW数据后手动解压 - 处理解压后的内容(转文本或直接使用RAW)
修改后的示例代码
DECLARE l_utl_resp UTL_HTTP.RESPONSE; l_raw_data RAW(32767); l_uncompressed RAW(32767); l_status_code PLS_INTEGER; l_content_enc VARCHAR2(100); BEGIN -- 假设已完成UTL_HTTP.SET_REQUEST等请求初始化,此处省略 l_utl_resp := UTL_HTTP.GET_RESPONSE(l_utl_req); -- 获取响应状态码和Content-Encoding头 l_status_code := UTL_HTTP.GET_RESPONSE_STATUS_CODE(l_utl_resp); BEGIN UTL_HTTP.GET_HEADER(l_utl_resp, 'Content-Encoding', l_content_enc); EXCEPTION WHEN UTL_HTTP.NO_DATA THEN l_content_enc := NULL; -- 无该响应头则设为NULL END; -- 读取原始响应数据并处理 LOOP UTL_HTTP.READ_RAW(l_utl_resp, l_raw_data, 32767); -- 判断是否需要手动解压 IF l_content_enc = 'gzip' THEN l_uncompressed := UTL_COMPRESS.GUNZIP(l_raw_data); -- 输出解压后的十六进制(如需文本可替换为UTL_RAW.CAST_TO_VARCHAR2(l_uncompressed)) DBMS_OUTPUT.PUT_LINE(RAWTOHEX(l_uncompressed)); ELSE DBMS_OUTPUT.PUT_LINE(RAWTOHEX(l_raw_data)); END IF; END LOOP; UTL_HTTP.END_RESPONSE(l_utl_resp); EXCEPTION WHEN UTL_HTTP.END_OF_BODY THEN UTL_HTTP.END_RESPONSE(l_utl_resp); WHEN UTL_HTTP.TRANSFER_TIMEOUT THEN UTL_HTTP.END_RESPONSE(l_utl_resp); WHEN OTHERS THEN IF UTL_HTTP.RESPONSE_IS_OPEN(l_utl_resp) THEN UTL_HTTP.END_RESPONSE(l_utl_resp); END IF; RAISE; END; /
关键说明
UTL_COMPRESS.GUNZIP函数需要数据库权限支持,若权限不足需DBA授予EXECUTE ON UTL_COMPRESS权限- 若响应的gzip数据分段过大,需先拼接所有RAW数据再统一解压,避免单段数据超过函数处理上限
- 异常处理中需确保响应对象被正确关闭,避免资源泄漏
内容的提问来源于stack exchange,提问作者Greg Reynolds
相关产品推荐
相关产品推荐

