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 的同时更新远程站点。