OpenEdge ABL JSON 到临时表:READ-JSON

Bob*_*Guy 0 progress-4gl openedge

我如何将其(如下)读取到临时表中:

{
  "args": {
  },
  "data": "{\"name\":\"morpheus11\",\"job\":\"leader1221\"}",
  "files": {
  },
  "form": {
  },
  "headers": {
    "Accept": "application\/json",
    "Content-Length": "40",
    "Content-Type": "application\/json",
    "Host": "httpbin.org",
    "User-Agent": "OpenEdge-HttpClient\/0.4.0 (UNIX\/64) OpenEdge\/99.2.99.0.9999 Lib-ABLSockets\/0.5.0",
    "X-Amzn-Trace-Id": "Root=1-9999998e-0e281713363302e331999999"
  },
  "json": {
    "job": "leader1221",
    "name": "morpheus11"
  },
  "origin": "888.53.150.88",
  "url": "https:\/\/httpbin.org\/post"
}
Run Code Online (Sandbox Code Playgroud)

这是我到目前为止所写的。现在导出流 dOut1 不产生任何东西。我的猜测是,我没有指定所有的表...我需要定义所有 json 节点,例如:Args、Data、Files、Headers、Origin 和 URL?感谢您的帮助

  def temp-table tt serialize-name 'json'
   field job  as char 
   field name as char.
  def dataset args for tt.

  def var dURL         as char          no-undo init "https://httpbin.org/post".
  def var dRequest     as IHttpRequest  no-undo.
  def var dResponse    as IHttpResponse no-undo.
  def var dClient      as IHttpClient   no-undo.
  def var dRequestResp as longchar      no-undo.  
  def var dJson        as JsonObject    no-undo. /* used by outbound Json and the return inbound Json */
  
  dClient = ClientBuilder:Build():Client.
  dJson   = new JsonObject() .
  dJson:Add("name","morpheus11").
  dJson:Add("job","leader1221").

  dRequest  = RequestBuilder:Post(dURL,dJson)
                    :ContentType('application/json')
                    :AcceptJson()
                    :Request.
  dResponse = dClient:Execute(dRequest).
  
  if dResponse:StatusCode <> 200 then do:
    message subst("dResponse:StatusCode = &1", dResponse:StatusCode).
  end. 
  else do:
    dJson = cast(dResponse:Entity, JsonObject).
    dJson:Write(dRequestResp, true).
    
    dataset args:read-json("longchar",dRequestResp).
    for each tt on error undo, return error on stop undo, return error:
      export stream dOut1 delimiter "|"
        tt.
    end. 
    output stream dOut1 close.
  end.
Run Code Online (Sandbox Code Playgroud)

谢谢

Mik*_*ner 5

JSON 与 ProDataset 不匹配。ProDatasets 由 JSON 对象表示,每个临时表都有一个嵌套的 JSON数组。

但是您可以将“json”对象直接读取到临时表的 tt 默认缓冲区中:

dJson = cast(dResponse:Entity, JsonObject).
dJson = dJson:GetJsonObject ("json") .
dJson:Write(dRequestResp, true).
buffer tt:read-json("longchar",dRequestResp).
Run Code Online (Sandbox Code Playgroud)

以及进一步的优化:不需要使用 longchar 作为中间:

dJson = cast(dResponse:Entity, JsonObject).
dJson = dJson:GetJsonObject ("json") .
buffer tt:read-json("JsonObject", dJson).
Run Code Online (Sandbox Code Playgroud)

这是我的完整示例:

/*------------------------------------------------------------------------
    File        : json.p
    Purpose     :

    Syntax      :

    Description :

    Author(s)   : mikef
    Created     : Sun Jan 07 16:08:47 CET 2024
    Notes       :

/sf/ask/5443656501/

  ----------------------------------------------------------------------*/

/* ***************************  Definitions  ************************** */

BLOCK-LEVEL ON ERROR UNDO, THROW.

USING Consultingwerk.Util.* FROM PROPATH.
using Progress.Json.ObjectModel.* from propath.
using OpenEdge.Net.HTTP.* from propath.

/* ***************************  Main Block  *************************** */

  def temp-table tt serialize-name 'json'
   field job  as char
   field name as char.
  def dataset args for tt.

  def var dURL         as char          no-undo init "https://httpbin.org/post".
  def var dRequest     as IHttpRequest  no-undo.
  def var dResponse    as IHttpResponse no-undo.
  def var dClient      as IHttpClient   no-undo.
  def var dRequestResp as longchar      no-undo.
  def var dJson        as JsonObject    no-undo. /* used by outbound Json and the return inbound Json */

  define stream dOut1 .

  OUTPUT STREAM dOut1 TO "Test/output.txt" .

  dClient = ClientBuilder:Build():Client.
  dJson   = new JsonObject() .
  dJson:Add("name","morpheus11").
  dJson:Add("job","leader1221").

  dRequest  = RequestBuilder:Post(dURL,dJson)
                    :ContentType('application/json')
                    :AcceptJson()
                    :Request.
  dResponse = dClient:Execute(dRequest).

  if dResponse:StatusCode <> 200 then do:
    message subst("dResponse:StatusCode = &1", dResponse:StatusCode).
  end.
  else do:
    dJson = cast(dResponse:Entity, JsonObject).

    dJson = dJson:GetJsonObject ("json") .

//    dJson:Write(dRequestResp, true).

    BUFFER tt:read-json("JsonObject", dJson).
    for each tt on error undo, return error on stop undo, return error:

//BufferHelper:ShowBuffer(BUFFER tt:HANDLE).

      export stream dOut1 delimiter "|"
        tt.
    end.
    output stream dOut1 close.
  end.
Run Code Online (Sandbox Code Playgroud)

和输出文件:

"leader1221"|"morpheus11"
Run Code Online (Sandbox Code Playgroud)