【问题标题】:DB2 SYSTOOLS.HTTPPUTCLOB ignores JSON in third parm, REQUESTMSG (body?)DB2 SYSTOOLS.HTTPPUTCLOB 在第三个参数 REQUESTMSG(正文?)中忽略 JSON
【发布时间】:2019-09-06 17:44:12
【问题描述】:

我正在尝试将 HTTP PUT 发送到远程 API 以更新数据。

我在 IBM i V7R3M0 上,使用 SQL 命令 SYSTOOLS.HTTPPUTCLOB。当我在 Postman 中进行类似测试时(针对相同的 URL、相同的标头、正文中的相同 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,但这些都没有改善结果。

**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 文档不应该使用与正文中相同的 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”变量包含此标头信息:

<?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>

【问题讨论】:

  • 有什么回应?
  • 请注意,HTTP 函数在幕后使用 Java……因为在作业中启动 JVM 会有开销,所以它会一直存在。因此,请重新考虑是否在大量交互式作业或短期批处理作业中使用。
  • 考虑使用Working with JSON in RPG 文章中所述的开源HTTP APIYAJL 端口
  • 响应头看起来不错,但您仍然没有显示响应中的内容。
  • 你的邮递员身体是什么样的?

标签: api db2 db2-400 rpgle http-put


【解决方案1】:

原来我需要包含 Content-Type 的标头:application/json。我将它添加到标题 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 ;

正确指定内容类型后,我能够仅使用已更改的字段填充正文,并在执行 PUT 的同时更新远程站点。

【讨论】:

    【解决方案2】:

    我没有发现任何问题...

    从标题中可以看出,Web 服务似乎正在接受您发送的内容。这有点令人惊讶,因为您只发送了两个属性。

    通常,PUT 需要实体的所有属性,PATCH 仅用于更新选定的属性。见RESTful API Design — PUT vs PATCH

    您确定 Postman 呼叫的工作方式与您想象的一样吗?您是否偶然在 postman 中执行 PATCH 而不是您在 Db2 for i 中使用的 PUT?

    您能否与网络服务提供商合作,看看他们到底发生了什么?

    【讨论】:

    • 邮递员肯定在工作。他们有一个门户网站,我可以在其中询问客户以查看当前地址。每次使用 Postman 都会立即更新地址。 HTTPPUTCLOB 绝对不会更新地址,因为我在每次测试后都会在门户网站中进行验证。我在两个调用中都发送了相同的两个属性。我可以咨询服务提供商,但我想我会先检查一下我是否使用了 IBM 命令错误。由于它适用于 Postman,我不认为这是他们的失败,但更有可能是我的 RPG 方面没有正确。
    • 如果您在 RPG 中做错了什么,我预计会在 200 之外出现一些问题 - 好的……您确定您没有在 postman 中使用 PATCH 吗?
    • 是的。我会在这里张贴一张图片,但不知道如何。但这绝对是PUT。我还没有在 Postman 中尝试过 Patch。可能我可以尝试获取整个响应 JSON 并制作一个模块,看看它是否适用于 RPG。你知道 HTTPPATCHCLOB 操作码吗?我没有遇到过那个命令。
    • 我尝试获取从 api 收到的整个响应,更改城市和 zip,然后将其放回 HTTPPUTCLOB。响应或门户网站上的城市和邮编没有变化。
    • @MikeRobinson 不愿意问“它是否已插入”,但您确定您正在查看相同的端点/环境吗?这不是 DEV/QA/PROD 问题吗?因为,再一次,我没有看到您的代码有任何问题......并且网络服务正在响应 200-OK....
    猜你喜欢
    • 2011-07-05
    • 1970-01-01
    • 1970-01-01
    • 2011-06-14
    • 2015-11-01
    • 1970-01-01
    • 2014-10-16
    • 2023-03-19
    • 1970-01-01
    相关资源
    最近更新 更多