T100作为客户端调用其他系统接口,我们用.net core创建一个API来测试T100
调用
四、T100调用其他系统接口
一、案例讲解
T100作为一个运营管理平台,有时候我们需要访问其他系统,比如我们可能
需要知道我们的网店某一时间点的订单量,就需要调用网店平台的API返回
订单量,对于有些需要TOKEN验证的API我们可以先获取到TOKEN,然后
将token放进post 的body中传到服务端进行验证
二、使用visual studio 2019创建一个 api接口
三、asp.net core api 源码
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace T100Interface.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpPost]
public IEnumerable<WeatherForecast> Get()
{
// 获取T100传递过来的数据
StreamReader stream = new StreamReader(Request.Body);
string body = stream.ReadToEndAsync().GetAwaiter().GetResult();
Console.WriteLine(body+" haha");
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
}
}
}
四、开发一个p批处理程式用来发送请求
#該程式未解開Section, 採用最新樣板產出!
#該程式非freestyle程式!
{<section id="cinp111.description" type="s" >}
#應用 a00 樣板自動產生(Version:3)
#+ Standard Version.....: SD版次:0001(1900-01-01 00:00:00), PR版次:
#+ Customerized Version.: SD版次:0001(2022-04-25 16:12:51), PR版次:
#+ Build......: 000000
#+ Filename...: cinp111
#+ Description: 接口程式測試
#+ Creator....: 00000(2022-04-25 16:12:51)
#+ Modifier...: 00000 -SD/PR-
{</section>}
{<section id="cinp111.global" type="s" >}
#應用 p01 樣板自動產生(Version:21)
#add-point:填寫註解說明 name="global.memo" name="global.memo"
#Memos
#end add-point
#add-point:填寫註解說明(客製用) name="global.memo_customerization"
#end add-point
#(ver:20) ---start---
#add-point:填寫註解說明(行業用) name="global.memo_industry"
#end add-point
#(ver:20) --- end ---
IMPORT os
IMPORT util
IMPORT FGL lib_cl_schedule
#add-point:增加匯入項目 name="global.import"
IMPORT xml
IMPORT com
#end add-point
SCHEMA ds
GLOBALS "../../cfg/top_global.inc"
GLOBALS "../../cfg/top_schedule.inc"
GLOBALS
DEFINE gwin_curr2 ui.Window
DEFINE gfrm_curr2 ui.Form
DEFINE gi_hiden_asign LIKE type_t.num5
DEFINE gi_hiden_exec LIKE type_t.num5
DEFINE gi_hiden_spec LIKE type_t.num5
DEFINE gi_hiden_exec_end LIKE type_t.num5
DEFINE g_chk_jobid LIKE type_t.num5
END GLOBALS
PRIVATE TYPE type_parameter RECORD
#add-point:自定背景執行須傳遞的參數(Module Variable) name="global.parameter"
#end add-point
wc STRING
END RECORD
DEFINE g_sql STRING #組 sql 用
DEFINE g_forupd_sql STRING #SELECT ... FOR UPDATE SQL
DEFINE g_error_show LIKE type_t.num5
DEFINE g_jobid STRING
DEFINE g_wc STRING
PRIVATE TYPE type_master RECORD
stagenow LIKE type_t.chr80,
wc STRING
END RECORD
#模組變數(Module Variables)
DEFINE g_master type_master
DEFINE g_condition_display LIKE type_t.chr1 #180813-00044
#add-point:自定義模組變數(Module Variable) name="global.variable"
PRIVATE TYPE type_result RECORD
dateb STRING,
c LIKE type_t.num5,
f LIKE type_t.num5,
summary STRING
END RECORD
#end add-point
#add-point:自定義客戶專用模組變數(Module Variable) name="global.variable_customerization"
#end add-point
#add-point:傳入參數說明 name="global.argv"
#end add-point
{</section>}
{<section id="cinp111.main" type="s" >}
MAIN
#add-point:main段define (客製用) name="main.define_customerization"
#end add-point
DEFINE ls_js STRING
DEFINE lc_param type_parameter
#add-point:main段define name="main.define"
#end add-point
#設定SQL錯誤記錄方式 (模組內定義有效)
WHENEVER ERROR CALL cl_err_msg_log
#add-point:初始化前定義 name="main.before_ap_init"
#end add-point
#依模組進行系統初始化設定(系統設定)
CALL cl_ap_init("cin","")
#add-point:定義背景狀態與整理進入需用參數ls_js name="main.background"
#end add-point
#背景(Y) 或半背景(T) 時不做主畫面開窗
IF g_bgjob = "Y" OR g_bgjob = "T" THEN
#排程參數由01開始,若不是1開始,表示有保留參數
LET ls_js = g_argv[01]
#CALL util.JSON.parse(ls_js,g_master) #p類主要使用l_param,此處不解析
#add-point:Service Call name="main.servicecall"
#end add-point
CALL cinp111_process(ls_js)
ELSE
#畫面開啟 (identifier)
OPEN WINDOW w_cinp111 WITH FORM cl_ap_formpath("cin",g_code)
#瀏覽頁簽資料初始化
CALL cl_ui_init()
#程式初始化
CALL cinp111_init()
#進入選單 Menu (="N")
CALL cinp111_ui_dialog()
#add-point:畫面關閉前 name="main.before_close"
#end add-point
#畫面關閉
CLOSE WINDOW w_cinp111
END IF
#add-point:作業離開前 name="main.exit"
#end add-point
#離開作業
CALL cl_ap_exitprogram("0")
END MAIN
{</section>}
{<section id="cinp111.init" type="s" >}
#+ 初始化作業
PRIVATE FUNCTION cinp111_init()
#add-point:init段define (客製用) name="init.define_customerization"
#end add-point
#add-point:ui_dialog段define name="init.define"
#end add-point
LET g_error_show = 1
LET gwin_curr2 = ui.Window.getCurrent()
LET gfrm_curr2 = gwin_curr2.getForm()
CALL cl_schedule_import_4fd()
CALL cl_set_combo_scc("gzpa003","75")
IF cl_get_para(g_enterprise,"","E-SYS-0005") = "N" THEN
CALL cl_set_comp_visible("scheduling_page,history_page",FALSE)
END IF
LET g_condition_display = "N" #180813-00044
#add-point:畫面資料初始化 name="init.init"
#end add-point
END FUNCTION
{</section>}
{<section id="cinp111.ui_dialog" type="s" >}
#+ 選單功能實際執行處
PRIVATE FUNCTION cinp111_ui_dialog()
#add-point:ui_dialog段define (客製用) name="ui_dialog.define_customerization"
#end add-point
DEFINE li_exit LIKE type_t.num5 #判別是否為離開作業
DEFINE li_idx LIKE type_t.num10
DEFINE ls_js STRING
DEFINE ls_wc STRING
DEFINE l_dialog ui.DIALOG
DEFINE lc_param type_parameter
#add-point:ui_dialog段define name="ui_dialog.define"
#end add-point
#add-point:ui_dialog段before dialog name="ui_dialog.before_dialog"
#end add-point
WHILE TRUE
#add-point:ui_dialog段before dialog2 name="ui_dialog.before_dialog2"
#end add-point
DIALOG ATTRIBUTES(UNBUFFERED,FIELD ORDER FORM)
#add-point:ui_dialog段construct name="ui_dialog.more_construct"
#end add-point
#add-point:ui_dialog段input name="ui_dialog.more_input"
#end add-point
#add-point:ui_dialog段自定義display array name="ui_dialog.more_displayarray"
#end add-point
SUBDIALOG lib_cl_schedule.cl_schedule_setting
SUBDIALOG lib_cl_schedule.cl_schedule_setting_exec_call
SUBDIALOG lib_cl_schedule.cl_schedule_select_show_history
SUBDIALOG lib_cl_schedule.cl_schedule_show_history
BEFORE DIALOG
LET l_dialog = ui.DIALOG.getCurrent()
CALL cinp111_get_buffer(l_dialog)
#180813-00044 ---start---
#顯示上次使用者下的條件
IF g_condition_display = "Y" THEN
CALL cl_qbe_display_condition('100001', g_user)
END IF
#180813-00044 --- end ---
#add-point:ui_dialog段before dialog name="ui_dialog.before_dialog3"
#end add-point
ON ACTION batch_execute
LET g_action_choice = "batch_execute"
#180813-00044 ---start---
#將此次查詢的條件儲存起來
LET g_condition_display = "Y"
CALL cl_qbe_auto_save()
#180813-00044 --- end ---
ACCEPT DIALOG
#add-point:ui_dialog段before_qbeclear name="ui_dialog.before_qbeclear"
#end add-point
ON ACTION qbeclear
CLEAR FORM
INITIALIZE g_master.* TO NULL #畫面變數清空
INITIALIZE lc_param.* TO NULL #傳遞參數變數清空
#add-point:ui_dialog段qbeclear name="ui_dialog.qbeclear"
#end add-point
ON ACTION history_fill
CALL cl_schedule_history_fill()
ON ACTION close
LET INT_FLAG = TRUE
EXIT DIALOG
ON ACTION exit
LET INT_FLAG = TRUE
EXIT DIALOG
#add-point:ui_dialog段action name="ui_dialog.more_action"
#end add-point
#主選單用ACTION
&include "main_menu_exit_dialog.4gl"
&include "relating_action.4gl"
#交談指令共用ACTION
&include "common_action.4gl"
CONTINUE DIALOG
END DIALOG
IF g_action_choice = "logistics" THEN
#清除畫面及相關資料
CLEAR FORM
INITIALIZE g_master.* TO NULL
LET g_wc = ' 1=2'
LET g_action_choice = ""
CALL cinp111_init()
CONTINUE WHILE
END IF
#檢查批次設定是否有錯(或未設定完成)
IF NOT cl_schedule_exec_check() THEN
CONTINUE WHILE
END IF
LET lc_param.wc = g_master.wc #把畫面上的wc傳遞到參數變數
#請在下方的add-point內進行把畫面的輸入資料(g_master)轉換到傳遞參數變數(lc_param)的動作
#add-point:ui_dialog段exit dialog name="process.exit_dialog"
#end add-point
LET ls_js = util.JSON.stringify(lc_param) #r類使用g_master/p類使用lc_param
IF INT_FLAG THEN
LET INT_FLAG = FALSE
EXIT WHILE
ELSE
IF g_chk_jobid THEN
LET g_jobid = g_schedule.gzpa001
ELSE
LET g_jobid = cl_schedule_get_jobid(g_prog)
END IF
#依照指定模式執行報表列印
CASE
WHEN g_schedule.gzpa003 = "0"
CALL cinp111_process(ls_js)
WHEN g_schedule.gzpa003 = "1"
LET ls_js = cinp111_transfer_argv(ls_js)
CALL cl_cmdrun(ls_js)
WHEN g_schedule.gzpa003 = "2"
CALL cl_schedule_update_data(g_jobid,ls_js)
WHEN g_schedule.gzpa003 = "3"
CALL cl_schedule_update_data(g_jobid,ls_js)
END CASE
IF g_schedule.gzpa003 = "2" OR g_schedule.gzpa003 = "3" THEN
CALL cl_ask_confirm3("std-00014","") #設定完成
END IF
LET g_schedule.gzpa003 = "0" #預設一開始 立即於前景執行
#add-point:ui_dialog段after schedule name="process.after_schedule"
#end add-point
#欄位初始資訊
CALL cl_schedule_init_info("all",g_schedule.gzpa003)
LET gi_hiden_asign = FALSE
LET gi_hiden_exec = FALSE
LET gi_hiden_spec = FALSE
LET gi_hiden_exec_end = FALSE
CALL cl_schedule_hidden()
END IF
END WHILE
END FUNCTION
{</section>}
{<section id="cinp111.transfer_argv" type="s" >}
#+ 轉換本地參數至cmdrun參數內,準備進入背景執行
PRIVATE FUNCTION cinp111_transfer_argv(ls_js)
#add-point:transfer_agrv段define (客製用) name="transfer_agrv.define_customerization"
#end add-point
DEFINE ls_js STRING
DEFINE la_cmdrun RECORD
prog STRING,
actionid STRING,
background LIKE type_t.chr1,
param DYNAMIC ARRAY OF STRING
END RECORD
DEFINE la_param type_parameter
#add-point:transfer_agrv段define name="transfer_agrv.define"
#end add-point
LET la_cmdrun.prog = g_prog
LET la_cmdrun.background = "Y"
LET la_cmdrun.param[1] = ls_js
#add-point:transfer.argv段程式內容 name="transfer.argv.define"
#end add-point
RETURN util.JSON.stringify( la_cmdrun )
END FUNCTION
{</section>}
{<section id="cinp111.process" type="s" >}
#+ 資料處理 (r類使用g_master為主處理/p類使用l_param為主)
PRIVATE FUNCTION cinp111_process(ls_js)
#add-point:process段define (客製用) name="process.define_customerization"
#end add-point
DEFINE ls_js STRING
DEFINE lc_param type_parameter
DEFINE li_stus LIKE type_t.num5
DEFINE li_count LIKE type_t.num10 #progressbar計量
DEFINE ls_sql STRING #主SQL
DEFINE li_p01_status LIKE type_t.num5
#add-point:process段define name="process.define"
#end add-point
#INITIALIZE lc_param TO NULL #p類不可以清空
CALL util.JSON.parse(ls_js,lc_param) #r類作業被t類呼叫時使用, p類主要解開參數處
LET li_p01_status = 1
#IF lc_param.wc IS NOT NULL THEN
# LET g_bgjob = "T" #特殊情況,此為t類作業鬆耦合串入報表主程式使用
#END IF
#add-point:process段前處理 name="process.pre_process"
#end add-point
#預先計算progressbar迴圈次數
IF g_bgjob <> "Y" THEN
#add-point:process段count_progress name="process.count_progress"
#end add-point
END IF
#主SQL及相關FOREACH前置處理
# DECLARE cinp111_process_cs CURSOR FROM ls_sql
# FOREACH cinp111_process_cs INTO
#add-point:process段process name="process.process"
#end add-point
# END FOREACH
IF g_bgjob = "N" THEN
#前景作業完成處理
#add-point:process段foreground完成處理 name="process.foreground_finish"
CALL cinp111_send()
#end add-point
CALL cl_ask_confirm3("std-00012","")
ELSE
#背景作業完成處理
#add-point:process段background完成處理 name="process.background_finish"
#end add-point
CALL cl_schedule_exec_call(li_p01_status)
END IF
#呼叫訊息中心傳遞本關完成訊息
CALL cinp111_msgcentre_notify()
END FUNCTION
{</section>}
{<section id="cinp111.get_buffer" type="s" >}
PRIVATE FUNCTION cinp111_get_buffer(p_dialog)
#add-point:process段define (客製用) name="get_buffer.define_customerization"
#end add-point
DEFINE p_dialog ui.DIALOG
#add-point:process段define name="get_buffer.define"
#end add-point
CALL cl_schedule_get_buffer(p_dialog)
#add-point:get_buffer段其他欄位處理 name="get_buffer.others"
#end add-point
END FUNCTION
{</section>}
{<section id="cinp111.msgcentre_notify" type="s" >}
PRIVATE FUNCTION cinp111_msgcentre_notify()
#add-point:process段define (客製用) name="msgcentre_notify.define_customerization"
#end add-point
DEFINE lc_state LIKE type_t.chr5
#add-point:process段define name="msgcentre_notify.define"
#end add-point
INITIALIZE g_msgparam TO NULL
#action-id與狀態填寫
LET g_msgparam.state = "process"
#add-point:msgcentre其他通知 name="msg_centre.process"
#end add-point
#呼叫訊息中心傳遞本關完成訊息
CALL cl_msgcentre_notify()
END FUNCTION
{</section>}
{<section id="cinp111.other_function" readonly="Y" type="s" >}
#add-point:自定義元件(Function) name="other.function"
#end add-point
{</section>}
################################################################################
# Descriptions...: 描述说明
# Memo...........:
# Usage..........: CALL s_aooi150_ins (传入参数)
# RETURNING 回传参数
# Input parameter: 传入参数变量1 传入参数变量说明1
# : 传入参数变量2 传入参数变量说明2
# Return code....: 回传参数变量1 回传参数变量说明1
# : 回传参数变量2 回传参数变量说明2
# Date & Author..: 日期 By 作者
# Modify.........:
################################################################################
PRIVATE FUNCTION cinp111_send()
DEFINE l_http_req com.HTTPRequest
DEFINE l_http_res com.HTTPResponse
DEFINE p_url STRING
DEFINE l_succ BOOLEAN
DEFINE l_str,l_reqstr STRING
DEFINE l_body STRING
DEFINE p_method LIKE type_t.chr100
LET l_succ = FALSE
LET l_str = ""
LET l_reqstr = "{'name':'张三','age':40}"
TRY
# 設置 HttpRequest START
LET l_http_req = com.HttpRequest.Create("http://192.168.0.42:5001/WeatherForecast") # 建立請求 requesst 物件
CALL l_http_req.setTimeOut(60) # 設定 request timeout
CALL l_http_req.setMethod("POST") # 設定Http method 设置成post才能在body中携带数据
CALL l_http_req.setCharset("UTF-8") # 設定編碼
CALL l_http_req.doTextRequest(l_reqstr) # 設定Http method 将l_reqstr放进body中传递到服务端
LET l_http_res = l_http_req.getResponse() #取得回傳 response 物件
IF l_http_res.getStatusCode() != 200 THEN
# server 回傳報錯
LET l_succ = FALSE
LET l_str = "HTTP Error ("||l_http_res.getStatusCode()||") ", l_http_res.getStatusDescription()
ELSE
# 取得 server 回傳 body content string
LET l_succ = TRUE
LET l_str = l_http_res.getTextResponse() # 取得 response body字串
END IF
CATCH
#get error from genero
LET l_succ = FALSE
LET l_str = "ERROR :",STATUS||" ("||SQLCA.SQLERRM||")"
END TRY
# 回傳結果
# RETURN l_succ,l_str
END FUNCTION
五、测试结果
六、关于一些API的问题
API我们可以去Genero Studio的帮助文档中查阅
总结
T100接口基本就这么多了,真正在开发的时候我们别忘了4GL中可以插入java
的包,其实调用接口也可以使用java来操作。有机会可以给大家出个教程玩一下。