oracle http使用步骤
前提:定义好参数
L_HTTP_REQUEST UTL_HTTP.REQ;
L_HTTP_RESPONSE UTL_HTTP.RESP;
L_RESPONSE_TEXT VARCHAR2(32767);
L_RESULT VARCHAR2(32767);
L_PARAM VARCHAR2(32767);
RETURNJSON JSON_OBJECT_T; -- 返回JSON
第一步:设置字体
UTL_HTTP.SET_BODY_CHARSET('UTF-8');
第二步:设置钱包安全, 如果是https 格式的,必须
-- 钱包安全 访问HTTPS必须
UTL_HTTP.SET_WALLET('file:钱包的位置','钱包密码');
第三步:初始化请求,GET 还是 POST
GET例子:
-- 初始化HTTP请求 GET
L_HTTP_REQUEST := UTL_HTTP.BEGIN_REQUEST(HTTP_URL, 'GET');
POST例子:
-- 设置用POST方式请求
L_HTTP_REQUEST := UTL_HTTP.BEGIN_REQUEST(HTTP_URL, 'POST');
--设置请求头部
UTL_HTTP.SET_HEADER(L_HTTP_REQUEST, 'Content-Type','application/json; encoding=utf-8');
UTL_HTTP.SET_HEADER(L_HTTP_REQUEST, 'Content-Length',LENGTHB(L_PARAM));
--RAW方式写入参数,可以避免中文变乱码
UTL_HTTP.WRITE_RAW(L_HTTP_REQUEST, UTL_RAW.CAST_TO_RAW(L_PARAM));
第四步:开始访问,
-- 获取HTTP响应
L_HTTP_RESPONSE := UTL_HTTP.GET_RESPONSE(L_HTTP_REQUEST);
第五步:获取响应结果,进行数据
-- 验证结果,获取响应返回的内容
IF L_HTTP_RESPONSE.STATUS_CODE = 200 THEN
UTL_HTTP.READ_TEXT(L_HTTP_RESPONSE, L_RESULT, 32767);
-- 关闭HTTP响应
UTL_HTTP.END_RESPONSE(L_HTTP_RESPONSE);
RETURNJSON := JSON_OBJECT_T.PARSE(L_RESULT);
dbms_output.put_line(L_RESULT);
END IF;
第六步:异常处理
-- 处理异常情况
WHEN OTHERS THEN
-- 关闭HTTP响应
UTL_HTTP.END_RESPONSE(L_HTTP_RESPONSE);
例子1: GET 获取微信公众号的TOKEN
CREATE OR REPLACE FUNCTION F_GET_ACCESS_TOKEN RETURN VARCHAR2 IS
L_GREETING VARCHAR2(2000);
/****************************************************************************
* 调用格式 :
* 作用 : 获取微信公众号的TOKEN 返回方式为 TOKEN,时间
*
* 创建人 :
* 创建时间 :
*
* 关联表 :
* 关联视图 :
*
* 更新人 :
* 更新时间 :
* 更新原因 :
* 更新内容 :
*
* *********************************************************************************/
L_HTTP_REQUEST UTL_HTTP.REQ;
L_HTTP_RESPONSE UTL_HTTP.RESP;
L_RESPONSE_TEXT VARCHAR2(32767);
GRANT_TYPE VARCHAR2(2000) := 'client_credential'; -- 获取ACCESS_TOKEN填写CLIENT_CREDENTIAL
APPID VARCHAR2(2000); -- 第三方用户唯一凭证
SECRET VARCHAR2(2000); -- 第三方用户唯一凭证密钥,即APPSECRET
URL_1 VARCHAR2(2000) := 'https://api.weixin.qq.com/cgi-bin/token';
HTTP_URL VARCHAR2(2000) := URL_1 || '?grant_type=' || GRANT_TYPE ||'&appid=' || APPID || '&secret=' || SECRET;
RETURNJSON JSON_OBJECT_T;
ACCESS_TOKEN VARCHAR2(2000);
EXPIRES_IN VARCHAR2(2000);
BEGIN
-- 参数
APPID := '*********************';
SECRET := '';
L_GREETING := '';
-- 字体
UTL_HTTP.SET_BODY_CHARSET('UTF-8');
-- 钱包安全 访问HTTPS必须
UTL_HTTP.SET_WALLET('file:/opt/oracle/oradata/******','*******');
-- 初始化HTTP请求
L_HTTP_REQUEST := UTL_HTTP.BEGIN_REQUEST(HTTP_URL, 'GET');
-- 获取HTTP响应
L_HTTP_RESPONSE := UTL_HTTP.GET_RESPONSE(L_HTTP_REQUEST);
--DBMS_OUTPUT.PUT_LINE(L_HTTP_RESPONSE.STATUS_CODE);
IF L_HTTP_RESPONSE.STATUS_CODE = 200 THEN
-- 读取响应内容
UTL_HTTP.READ_TEXT(L_HTTP_RESPONSE, L_RESPONSE_TEXT, 32767);
-- 输出响应内容
--DBMS_OUTPUT.PUT_LINE(L_RESPONSE_TEXT);
-- 解析JSON
RETURNJSON := JSON_OBJECT_T.PARSE(L_RESPONSE_TEXT);
ACCESS_TOKEN := RETURNJSON.GET_STRING('access_token');
EXPIRES_IN := RETURNJSON.GET_STRING('expires_in');
L_GREETING := ACCESS_TOKEN || ',' || EXPIRES_IN;
-- 返回值判断
IF ACCESS_TOKEN IS NULL OR EXPIRES_IN IS NULL THEN
L_GREETING := '';
ELSE
L_GREETING := ACCESS_TOKEN || ',' || EXPIRES_IN;
END IF;
-- 返回TOKEN和时间
-- DBMS_OUTPUT.PUT_LINE(L_GREETING);
END IF;
-- 关闭HTTP响应
UTL_HTTP.END_RESPONSE(L_HTTP_RESPONSE);
-- 输出对应值
RETURN L_GREETING;
EXCEPTION
-- 处理异常情况
WHEN OTHERS THEN
UTL_HTTP.END_RESPONSE(L_HTTP_RESPONSE);
L_GREETING := 'err';
RETURN L_GREETING;
END;
例子2: POST 微信 开始发送消息
这里,执行的时候测试数据发生问题,加上第一步
-- 字体
UTL_HTTP.SET_BODY_CHARSET('UTF-8');
报错,去掉没有问题,原因没有找到,但是不影响使用
CREATE OR REPLACE PROCEDURE P_WX_SEND_MASSAGE AS
/****************************************************************************
* 调用格式 :
* 作用 : 微信 开始发送消息
*
* 创建人 :
* 创建时间 :
*
* 关联表 :
* 关联视图 :
*
* 更新人 :
* 更新时间 :
* 更新原因 :
* 更新内容 :
*
* *********************************************************************************/
V_SQLCODE VARCHAR2(4000); -- 错误代码
V_SQLERRM VARCHAR2(4000); -- 错误内容
L_HTTP_REQUEST UTL_HTTP.REQ;
L_HTTP_RESPONSE UTL_HTTP.RESP;
--L_HTTP_HEADERS UTL_HTTP.REQ_HEADERS;
L_RESULT VARCHAR2(32767);
L_PARAM VARCHAR2(32767);
URL_1 VARCHAR2(4000) := 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token='; -- 微信URL
HTTP_URL VARCHAR2(2000);
WECHAT_IDS VARCHAR2(4000) := 1; -- 微信公众号 测试需要
TOKEN VARCHAR2(4000);
TOUSER VARCHAR2(4000); -- 接收者OPENID
TEMPLATE_ID VARCHAR2(4000) := '*************************-*************'; -- 模板ID
TZ_URL VARCHAR2(4000) := 'https://*******************?USERNAME='; --模板跳转链接
IS_OPENID NUMBER; -- 验证OPENID
IS_TOKEN NUMBER; -- 验证TOKEN
LISTOBJ JSON_OBJECT_T;
DATAOBJ CLOB;
RETURNJSON JSON_OBJECT_T; -- 返回JSON
BEGIN
-- 循环取消息
FOR MASSAGE IN (SELECT *
FROM WX_MASSAGE
WHERE DEL_FLAG = 1
AND M_STATUS IN (1, 2) -- 未发送 发送失败
AND CREATE_TIME >= SYSDATE - 2 -- 消息只发送有效期2天内的
) LOOP
-- 1. 先获取接收者的 OPENID
SELECT COUNT(*)
INTO IS_OPENID
FROM CENTRE_USER_WECHAT_OPENID
WHERE DEL_FLAG = 1
AND LONGIN = MASSAGE.APP_USER
AND WECHAT_ID = WECHAT_IDS;
-- 1.1 判定是否有值
IF IS_OPENID <> 0 THEN
SELECT OPENID
INTO TOUSER
FROM CENTRE_USER_WECHAT_OPENID
WHERE DEL_FLAG = 1
AND LONGIN = MASSAGE.APP_USER
AND WECHAT_ID = WECHAT_IDS;
-- 2. 获取ACCESS_TOKEN 验证TOKEN
-- 2.1验证TOKEN
IS_TOKEN := 2;
-- 循环获取是否有效,无效即重新获取
WHILE IS_TOKEN <= 5 LOOP
SELECT ACCESS_TOKEN
INTO TOKEN
FROM CENTRE_WECHAT_ACCESS_TOKEN
WHERE DEL_FLAG = 1
AND WECHAT_ID = WECHAT_IDS;
-- 验证是否有效
SELECT F_VERIFY_WX_ACCESS_TOKEN(TOKEN) INTO IS_TOKEN FROM DUAL;
IF IS_TOKEN = 1 THEN
EXIT; -- 当 COUNTER 等于 1 时跳出循环
ELSE
P_GET_WX_ACCESS_TOKEN(WECHAT_IDS);
END IF;
IS_TOKEN := IS_TOKEN + 1;
END LOOP;
-- 如果结果不是正常的,跳出这次消息的循环,不是用户信息的问题, 消息先不发送
IF IS_TOKEN <> 1 THEN
CONTINUE;
END IF;
-- 3. 组合参数,等待发送
-- 钱包安全 访问HTTPS必须
UTL_HTTP.SET_WALLET('file:/opt/oracle/oradata/******/*****', '*******');
HTTP_URL := URL_1 || TOKEN;
LISTOBJ := NEW JSON_OBJECT_T;
SELECT JSON_OBJECT('touser' VALUE TOUSER,
'template_id' VALUE TEMPLATE_ID,
'client_msg_id' VALUE client_msg_id,
'url' VALUE url || MASSAGE.APP_USER,
'data' value
JSON_OBJECT('thing5' VALUE
JSON_OBJECT('value' value thing5),
'thing13' VALUE
JSON_OBJECT('value' value thing13),
'thing6' VALUE
JSON_OBJECT('value' value thing6),
'thing4' VALUE
JSON_OBJECT('value' value thing4),
'time11' VALUE
JSON_OBJECT('value' value time11)))
INTO DATAOBJ
FROM WX_MASSAGE
WHERE PKID = MASSAGE.PKID;
LISTOBJ := JSON_OBJECT_T.parse(DATAOBJ);
--设置请求的路径
l_param := LISTOBJ.to_string();
-- 设置用POST方式请求
L_HTTP_REQUEST := UTL_HTTP.BEGIN_REQUEST(HTTP_URL, 'POST');
--设置请求头部
UTL_HTTP.SET_HEADER(L_HTTP_REQUEST,'Content-Type','application/json; encoding=utf-8');
UTL_HTTP.SET_HEADER(L_HTTP_REQUEST,'Content-Length',LENGTHB(l_param));
--RAW方式写入参数,可以避免中文变乱码
UTL_HTTP.WRITE_RAW(L_HTTP_REQUEST, UTL_RAW.CAST_TO_RAW(L_PARAM));
-- 获取HTTP响应
L_HTTP_RESPONSE := UTL_HTTP.GET_RESPONSE(L_HTTP_REQUEST);
--4. 验证结果,修改日志发送成功的状态
IF L_HTTP_RESPONSE.STATUS_CODE = 200 THEN
UTL_HTTP.READ_TEXT(L_HTTP_RESPONSE, L_RESULT, 32767);
UTL_HTTP.END_RESPONSE(L_HTTP_RESPONSE);
RETURNJSON := JSON_OBJECT_T.PARSE(L_RESULT);
IF L_RESULT LIKE '%errcode%' THEN
IF RETURNJSON.GET_STRING('errcode') = 0 THEN
-- 发送成功
UPDATE WX_MASSAGE
SET M_STATUS = 0, UPDATE_TIME = SYSDATE
WHERE PKID = MASSAGE.PKID;
ELSE
-- 发送失败
UPDATE WX_MASSAGE
SET M_STATUS = 2, UPDATE_TIME = SYSDATE
WHERE PKID = MASSAGE.PKID;
END IF;
ELSE
-- 发送失败
UPDATE WX_MASSAGE
SET M_STATUS = 2, UPDATE_TIME = SYSDATE
WHERE PKID = MASSAGE.PKID;
END IF;
END IF;
ELSE
-- 发送失败
UPDATE WX_MASSAGE
SET M_STATUS = 2, UPDATE_TIME = SYSDATE
WHERE PKID = MASSAGE.PKID;
END IF;
COMMIT;
END LOOP;
/*异常*/ -------------------异常-------------------------
EXCEPTION
WHEN OTHERS THEN
UTL_HTTP.END_RESPONSE(L_HTTP_RESPONSE);
V_SQLCODE := SQLCODE;
V_SQLERRM := SUBSTR(SQLERRM, 1, 2000);
DBMS_OUTPUT.PUT_LINE(V_SQLCODE || V_SQLERRM);
END;