Oracle存储过程调用API失败:遇ORA-28860等SSL错误求助
问题描述
开发了Oracle存储过程调用公司子域名下的HTTPS API,该API通过Postman测试正常,POST请求JSON如下:
{ "student_id": "15", "created_by": "1" }
存储过程代码:
PROCEDURE create_bb_user ( student_id IN NUMBER, created_by IN NUMBER ) IS req utl_http.req; res utl_http.resp; url VARCHAR2(4000) := 'https://...'; name VARCHAR2(4000); buffer CLOB; content CLOB := '{"student_id":"' || student_id || '", "created_by":"' || created_by || '"}'; BEGIN dbms_output.put_line(content); req := utl_http.begin_request(url, 'POST', ' HTTP/1.1'); utl_http.set_header(req, 'user-agent', 'mozilla/4.0'); utl_http.set_header(req, 'Content-Type', 'application/json'); utl_http.set_header(req, 'Content-Length', length(content)); utl_http.write_text(req, content); dbms_output.put_line('buffer1'); res := utl_http.get_response(req); dbms_output.put_line('buffer2'); BEGIN LOOP utl_http.read_line(res, buffer); dbms_output.put_line(buffer); END LOOP; utl_http.end_response(res); EXCEPTION WHEN utl_http.end_of_body THEN utl_http.end_response(res); WHEN OTHERS THEN utl_http.end_response(res); END; EXCEPTION WHEN OTHERS THEN utl_http.end_response(res); END;
调用方式:
BEGIN PKG_LC_CALL_APIS.CREATE_BB_USER (15, 1); END;
执行时收到错误:
Error report -
- ORA-29273: HTTP request failure
- ORA-06512: in "SYS.UTL_HTTP", line 1527
- ORA-29261: wrong argument
- ORA-06512: in "SCE.PKG_LC_CALL_APIS", line 215
- ORA-29273: HTTP request failure
- ORA-06512: in "SYS.UTL_HTTP", line 1130
- ORA-28860: Fatal SSL error
- ORA-06512: on line 2
- 00000 - "HTTP request failed".
- *Cause: The UTL_HTTP package failed to execute the HTTP request.
- *Action: Use get_detailed_sqlerrm to check the detailed error message. Fix the error and retry the HTTP request.
已配置数据库到API服务器的访问列表,询问是否需要额外配置。
解决方案
1. 修复参数错误(ORA-29261)
utl_http.begin_request的第三个参数' HTTP/1.1'前面多了空格,导致参数无效,修改为:
req := utl_http.begin_request(url, 'POST', 'HTTP/1.1');
2. 解决SSL证书信任问题(ORA-28860)
调用HTTPS接口时,Oracle需要信任API服务器的SSL证书,需完成以下配置:
- 创建并配置Oracle钱包:用
orapki工具创建钱包,将API服务器的CA证书导入钱包。 - 指定UTL_HTTP使用钱包:在存储过程中添加钱包配置,示例:
也可在数据库的utl_http.set_wallet('file:/path/to/your/wallet', 'wallet_password');sqlnet.ora文件中全局配置钱包位置:WALLET_LOCATION = (SOURCE = (METHOD = FILE)(METHOD_DATA = (DIRECTORY = /path/to/wallet))) SSL_CLIENT_AUTHENTICATION = FALSE - 验证证书链:确保导入的是API服务器证书对应的根CA或中间CA,避免证书链不完整引发SSL错误。
3. 其他优化点
- 修正Content-Length计算:
content是CLOB类型,length(content)无法正确获取长度,替换为:utl_http.set_header(req, 'Content-Length', dbms_lob.getlength(content)); - 优化异常处理:全局异常分支中直接调用
utl_http.end_response(res)可能因res未初始化报错,增加判断逻辑:EXCEPTION WHEN OTHERS THEN IF utl_http.is_response_open(res) THEN utl_http.end_response(res); END IF;
内容的提问来源于stack exchange,提问作者Felipe Renovato
相关产品推荐
相关产品推荐

