DB2 SYSTOOLS.HTTPPUTCLOB 忽略第三个参数 REQUESTMSG (body?) 中的 JSON
DB2 SYSTOOLS.HTTPPUTCLOB ignores JSON in third parm, REQUESTMSG (body?)
我正在尝试将 HTTP PUT 发送到远程 API 以更新数据。
我在 IBM i V7R3M0 上,使用 SQL 命令 SYSTOOLS.HTTPPUTCLOB。当我在 Postman 中进行类似测试时(在 body 中相同的 URL、相同的 header、相同的 JSON),远程数据更新成功。
但是对于 SYSTOOLS.HTTPPUTCLOB(:myUrl, :myHdr, :myRequest),我得到了响应,但没有数据发生变化。
对于此测试,我正在尝试更新客户的城市和邮政编码。
IBM 说 CLOB 参数是 CCSID 1208,所以这就是我正在使用的。 https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_74/rzajq/rzajqudfhttpputclob.htm
我包括了 CCSID 37 只是为了我可以阅读它。我已尝试传递 CCSID 37 参数,而不是指定 CCSID,none 改善了结果。
**free
dcl-s customers char(7);
dcl-s url varchar(2000);
dcl-s response varchar(5000);
dcl-s reqClob SQLTYPE(CLOB:5000) ccsid(1208);
dcl-s hdrClob SQLTYPE(CLOB:5000) ccsid(1208);
dcl-s reqClob37 SQLTYPE(CLOB:5000) ccsid(37);
dcl-s hdrClob37 SQLTYPE(CLOB:5000) ccsid(37);
customers = 'TEST123'; //my test customer
// format a JSON document
exec sql select json_object(
'zip' value '98756',
'city' value 'Chicago'
)
into :reqClob
from SYSIBM.SYSDUMMY1;
url = 'https://*remoteapi*/customers/'+%Trim(customers);
// format my XML headers
exec sql
with T(tname, tvalue) as (Values
('Authorization', 'Basic *mybase64id*'),
('x-client-id', '111111'),
('x-customer-primary-key', 'customer_number'))
SELECT
XMLGROUP(RTRIM(T.tname) AS "name", RTRIM(T.tvalue) AS "value"
OPTION ROW "header" ROOT "httpHeader" AS ATTRIBUTES)
INTO :hdrClob
From T ;
// convert so I can read it in debug
exec sql select :reqClob INTO :reqClob37 from sysibm.sysdummy1;
exec sql select :hdrClob INTO :hdrClob37 from sysibm.sysdummy1;
// PUT it
exec SQL
select SYSTOOLS.HTTPPUTCLOB(:url, :hdrClob, :reqClob)
into :response
from SYSIBM.SYSDUMMY1;
*inlr = *on;
return;
我在 "response" 变量中成功接收到客户信息。但是 city 和 zip 值是远程站点的旧值,站点上的值保持不变。 SQLCOD 和 SQLSTT 值为零。
同样,当我在 Postman 中做同样的事情时,响应有我的新值,并且数据在远程站点上更新。
在我看来,第三个参数(在本例中 "reqClob")被忽略了。当使用像 Postman 这样的工具时,第三个参数中的 JSON 文档不应该导致与 body 中相同的 HTTP PUT 更新吗?
*编辑
... 试图获得更多信息 运行 详细版本 HTTPPUTCLOBVERBOSE。我添加了这段代码
dcl-s verboseHdr SQLTYPE(CLOB:5000) ccsid(37);
exec SQL
select varchar(responseMsg,2048), varchar(responseHttpHeader,1024)
into :response, :verboseHdr
from table (
SYSTOOLS.HTTPPUTCLOBVERBOSE(:url2, :hdrClob, :reqClob));
"verboseHdr" 变量包含此 header 信息:
<?xml version="1.0" encoding="UTF-8" ?><httpHeader responseCode="200"><responseMessage>OK</responseMessage><header name="HTTP_RESPONSE_CODE" value="HTTP/1.1 200 OK"/><header name="Server" value="Apache/2.4.25 (Ubuntu)"/><header name="Cache-Control" value="no-cache"/><header name="X-Content-Type-Options" value="nosniff"/><header name="Connection" value="keep-alive"/><header name="Vary" value="Authorization"/><header name="Content-Length" value="688"/><header name="Date" value="Fri, 06 Sep 2019 19:32:07 GMT"/><header name="Content-Type" value="application/json"/></httpHeader>
我没有发现任何问题...
来自 header,Web 服务似乎正在接受您发送的内容。这有点令人惊讶,因为您只发送了两个属性。
通常,PUT 需要实体的所有属性,PATCH 仅用于更新选定的属性。见 RESTful API Design — PUT vs PATCH
您确定 Postman 呼叫工作正常吗?您是否偶然在邮递员中进行了 PATCH,而不是在 Db2 for i 中使用的 PUT?
您能否与网络服务提供商合作,了解他们的情况?
原来我需要为 Content-Type 添加 header:application/json。我将其添加到 header SQL。
exec sql
with T(tname, tvalue) as (Values
('Authorization', 'Basic *mybase64id*'),
('x-client-id', '111111'),
('x-customer-primary-key', 'customer_number'),
('Content-Type', 'application/json'))
SELECT
XMLGROUP(RTRIM(T.tname) AS "name", RTRIM(T.tvalue) AS "value"
OPTION ROW "header" ROOT "httpHeader" AS ATTRIBUTES)
INTO :hdrClob
From T ;
在正确指定内容类型的情况下,我能够仅使用更改的字段填充 body,并在执行 PUT 的同时更新远程站点。
我正在尝试将 HTTP PUT 发送到远程 API 以更新数据。
我在 IBM i V7R3M0 上,使用 SQL 命令 SYSTOOLS.HTTPPUTCLOB。当我在 Postman 中进行类似测试时(在 body 中相同的 URL、相同的 header、相同的 JSON),远程数据更新成功。
但是对于 SYSTOOLS.HTTPPUTCLOB(:myUrl, :myHdr, :myRequest),我得到了响应,但没有数据发生变化。
对于此测试,我正在尝试更新客户的城市和邮政编码。
IBM 说 CLOB 参数是 CCSID 1208,所以这就是我正在使用的。 https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_74/rzajq/rzajqudfhttpputclob.htm
我包括了 CCSID 37 只是为了我可以阅读它。我已尝试传递 CCSID 37 参数,而不是指定 CCSID,none 改善了结果。
**free
dcl-s customers char(7);
dcl-s url varchar(2000);
dcl-s response varchar(5000);
dcl-s reqClob SQLTYPE(CLOB:5000) ccsid(1208);
dcl-s hdrClob SQLTYPE(CLOB:5000) ccsid(1208);
dcl-s reqClob37 SQLTYPE(CLOB:5000) ccsid(37);
dcl-s hdrClob37 SQLTYPE(CLOB:5000) ccsid(37);
customers = 'TEST123'; //my test customer
// format a JSON document
exec sql select json_object(
'zip' value '98756',
'city' value 'Chicago'
)
into :reqClob
from SYSIBM.SYSDUMMY1;
url = 'https://*remoteapi*/customers/'+%Trim(customers);
// format my XML headers
exec sql
with T(tname, tvalue) as (Values
('Authorization', 'Basic *mybase64id*'),
('x-client-id', '111111'),
('x-customer-primary-key', 'customer_number'))
SELECT
XMLGROUP(RTRIM(T.tname) AS "name", RTRIM(T.tvalue) AS "value"
OPTION ROW "header" ROOT "httpHeader" AS ATTRIBUTES)
INTO :hdrClob
From T ;
// convert so I can read it in debug
exec sql select :reqClob INTO :reqClob37 from sysibm.sysdummy1;
exec sql select :hdrClob INTO :hdrClob37 from sysibm.sysdummy1;
// PUT it
exec SQL
select SYSTOOLS.HTTPPUTCLOB(:url, :hdrClob, :reqClob)
into :response
from SYSIBM.SYSDUMMY1;
*inlr = *on;
return;
我在 "response" 变量中成功接收到客户信息。但是 city 和 zip 值是远程站点的旧值,站点上的值保持不变。 SQLCOD 和 SQLSTT 值为零。
同样,当我在 Postman 中做同样的事情时,响应有我的新值,并且数据在远程站点上更新。
在我看来,第三个参数(在本例中 "reqClob")被忽略了。当使用像 Postman 这样的工具时,第三个参数中的 JSON 文档不应该导致与 body 中相同的 HTTP PUT 更新吗?
*编辑 ... 试图获得更多信息 运行 详细版本 HTTPPUTCLOBVERBOSE。我添加了这段代码
dcl-s verboseHdr SQLTYPE(CLOB:5000) ccsid(37);
exec SQL
select varchar(responseMsg,2048), varchar(responseHttpHeader,1024)
into :response, :verboseHdr
from table (
SYSTOOLS.HTTPPUTCLOBVERBOSE(:url2, :hdrClob, :reqClob));
"verboseHdr" 变量包含此 header 信息:
<?xml version="1.0" encoding="UTF-8" ?><httpHeader responseCode="200"><responseMessage>OK</responseMessage><header name="HTTP_RESPONSE_CODE" value="HTTP/1.1 200 OK"/><header name="Server" value="Apache/2.4.25 (Ubuntu)"/><header name="Cache-Control" value="no-cache"/><header name="X-Content-Type-Options" value="nosniff"/><header name="Connection" value="keep-alive"/><header name="Vary" value="Authorization"/><header name="Content-Length" value="688"/><header name="Date" value="Fri, 06 Sep 2019 19:32:07 GMT"/><header name="Content-Type" value="application/json"/></httpHeader>
我没有发现任何问题...
来自 header,Web 服务似乎正在接受您发送的内容。这有点令人惊讶,因为您只发送了两个属性。
通常,PUT 需要实体的所有属性,PATCH 仅用于更新选定的属性。见 RESTful API Design — PUT vs PATCH
您确定 Postman 呼叫工作正常吗?您是否偶然在邮递员中进行了 PATCH,而不是在 Db2 for i 中使用的 PUT?
您能否与网络服务提供商合作,了解他们的情况?
原来我需要为 Content-Type 添加 header:application/json。我将其添加到 header SQL。
exec sql
with T(tname, tvalue) as (Values
('Authorization', 'Basic *mybase64id*'),
('x-client-id', '111111'),
('x-customer-primary-key', 'customer_number'),
('Content-Type', 'application/json'))
SELECT
XMLGROUP(RTRIM(T.tname) AS "name", RTRIM(T.tvalue) AS "value"
OPTION ROW "header" ROOT "httpHeader" AS ATTRIBUTES)
INTO :hdrClob
From T ;
在正确指定内容类型的情况下,我能够仅使用更改的字段填充 body,并在执行 PUT 的同时更新远程站点。