【ERP】鼎捷T100接口开发操作指南——含接口调用与调试
文章目录
一、T100作为服务端
当T100
作为服务端时,提供的接口地址都大致相同,只有主机IP和区域的编码稍有区别,作业都为awsp920
,但是为什么都是awsp920
就不得而知了。
区域别 | RESTful 接口 |
---|---|
正式区 | http://T100主机IP/wstopprd/ws/r/awsp920 |
测试区 | http://T100主机IP/wtoptst/ws/r/awsp920 |
1、RESTful API介绍
RESTful API
是一种设计风格,这种风格使 API
设计具有整体一致性:
- 易于维护、扩展,并且充分利用
HTTP
协议的特点。 RESTful
通过HTTP
协议进行数据传送。RESTful
交换数据的格式由双方自行定义。RESTful
传送的内容可以是XML
或JSON
格式。RESTful
可通过GET
、POST
等方式请求不同的服务。
T100
结合RESTful
及Web service
的优点:
- 使用单一的
Restful
整合接口awsp920
,client
端无需因为使用不同的服务去变换网址。 T100
支持POST
请求服务,目的是为了交换ERP
的数据内容。- 使用
JSON
在数据处理上较为简洁且轻量化。
2、T100 RESTful API开发流程图
3、测试T100 RESTful 接口运作是否正常
方法一
通过API
请求工具,对某一个服务进行测试请求,查看是否能够执行成功,下面以ApiFox
软件为例,也可以使用PostMan
等其他接口测试工具进行测试。
如上图所示,调用方法选择post
,接口地址需要换上自己的T100
服务器IP,请求体选择json
格式进行数据传输。请求内容如下:
{
"key": "f5458f5c0f9022db743a7c0710145903",//key和type随意
"type": "sync",
"host": {
"prod": "APP",
"ip": "10.40.71.91",//服务器的ip地址,非必填
"lang": "zh_TW",//语言别:zh_TW/zh_CN
"acct": "tiptop",//存在T100的使用者
"timestamp": "20151211123204361"
},
"service": {
"prod": "T100",
"name": "employee.name.get",//指定T100的服务名称,即接口名称
"ip": "10.40.40.18",//服务器的ip地址,非必填
"id": "topprd"//区域,正式区为topprd,测试区为toptst
},
"datakey": {
"EntId": "99",// T100企业编码 (g_enterprise)
"CompanyId": "DSCTC"//营运据点(g_site)
},
"payload": {
"std_data": {
"parameter": {
"employee_no": "07375" //传输参数
}
}
}
}
返回结果如下:
{
"srvver": "1.0",
"srvcode": "000",
"datakey": null,
"payload": {
"std_data": {
"execution": {
"code": "0",//错误码, 0表示成功正常,非 0 则为错误
"sql_code": "0",
"description": "執行成功!"
},
"parameter": {
"employee_no": "07375",
"employee_name": "XXX"
}
}
}
}
方法二
在浏览器中,直接输入接口请求的地址,如果显示Restful service is ok
则表示T100
的RESTful
接口功能正常。
4、注册接口服务名
首先打开作业azzi700
,点击操作栏中的加号按钮,进行新建接口作业,接口需要在这里进行注册创建。
这里需要注意以下几点:
-
在客制模式下,服务规格编号不能重复,并且格式必须为
cwssp+
三位数字,否则可能会出现如下情况的报错;cwss
开头的情况:如果不以
cwss
开头的情况: -
WS服务名称
即接口请求时的接口名称,不要出现中文; -
服务版本根据实际情况进行选择:
-
信息内容格式即数据传输的格式,分为
json
和xml
,现在基本上都是json
格式,可以根据实际情况进行选择:
- 产品别根据自己的实际情况进行选择即可:
数据填写完成后,点击操作栏左上角的✔
图标进行确定。随后会出现API文档语系清单
这个菜单栏,这个菜单栏是存放接口文档的地方,可以进行接口文档的上传和下载。
如果有API
文档,那么会出现如下界面:
5、下载程序
打开T100
设计器,点击操作栏中的下载程序,进行接口作业的程序下载。
随后会打开一个名为adzp050
的作业,你也可以在Xshell
中打开这个作业进行程序的下载。
在左侧输入框中输入刚刚创建的作业编号,搜索出来后进行选择,然后点击签出,选择后进行下载即可。
下载进度条到达百分百后,则表示程序下载成功了,这个文件会存放在之前在T100
设计器设置的文件夹中。
回到T100
设计器,将下载下来的文件进行打开,程序文件的后缀是.tzc
打开后画面如下:
如果不执行其他业务逻辑的话,直接点击操作栏中的上传按钮,那么这个接口就算是完成了。
6、接口调用
接口请求的方式与前文中介绍的大同小异,如果不清楚或者忘记创建时的接口名称了,那么可以打开awsq990
这个作业进行查询。在集成服务检测中查看接口方式与集成方式。其中集成方式就是当前环境的接口地址,这个地址可能存在服务器IP错误,还需要根据服务器的IP自行检测纠正。
在服务信息查询菜单中,你可以根据日期和服务名称等信息进行接口请求的信息查询,接口被调用的时间,哪个接口被调用,是否成功等。
其中红色的就是接口报错的情况,可以查看接口报错的日志等信息。
接口调用后,可以看到返回结果是成功的,这就表示接口是通的,可以根据实际需求修改。
如果使用的是Web service
,即XML
格式的数据,那么需要使用T100 Soapui
进行接口测试,具体流程参考T100 Soapui
的操作手册。
7、代码编写
(1)定义传入参数
#add-point:自定义客户专用模块变量(Module Variable)
PRIVATE TYPE type_detail RECORD #传入单身数组
isagseq LIKE isag_t.isagseq, #项次
isag001 LIKE isag_t.isag001, #来源类型
isag002 LIKE isag_t.isag002, #来源单号
isag003 LIKE isag_t.isag003, #来源项次
isag009 LIKE isag_t.isag009, #料号
isag004 LIKE isag_t.isag004, #发票数量
isag005 LIKE isag_t.isag005, #发票单位
isag101 LIKE isag_t.isag101, #原币单价
isag105 LIKE isag_t.isag105 #原币税后金额
END RECORD
PRIVATE TYPE type_master RECORD #传入单头数组
isaf003 LIKE isaf_t.isaf003, #账款客户
isafdocdt LIKE isaf_t.isafdocdt, #单据日期
isaf018 LIKE isaf_t.isaf018, #税率
isafud001 LIKE isaf_t.isafud001, #EDB对账单号
END RECORD
PRIVATE TYPE type_return RECORD #返回数组
code LIKE type_t.chr20,
sqlcode LIKE type_t.chr20,
description LIKE type_t.chr1000,
orderNo LIKE type_t.chr50 #EDB销退单单号
END RECORD
DEFINE l_master RECORD
requestData DYNAMIC ARRAY OF type_master
END RECORD
DEFINE l_return RECORD
reValue DYNAMIC ARRAY OF type_return
END RECORD
(2)返回输出参数
#返回值
CALL cl_aws_json_addParam(util.JSONObject.fromFGL(l_return))
(3)从JSON中获取参数
#取回 datakey 资料内容
LET g_ent = cl_aws_json_getValue("datakey","EntId")
LET g_company = cl_aws_json_getValue("datakey","CompanyId")
LET l_json_obj = cl_aws_json_getParam()
#将data 转入l_master record
CALL l_json_obj.toFGL(l_master)
IF l_json_obj IS NULL THEN
LET g_status.code = "wss-00216" #读入json 发生问题
RETURN
END IF
#检查传入datakey是否为空
IF cl_null(g_ent) THEN
LET g_status.code = "wss-00138"
LET l_str = cl_replace_err_msg(cl_getmsg('wss-00138',g_dlang),'EntId')
LET g_status.description = l_str
RETURN
END IF
IF cl_null(g_company) THEN
LET g_status.code = "wss-00138"
LET l_str = cl_replace_err_msg(cl_getmsg('wss-00138',g_dlang),'CompanyId')
LET g_status.description = l_str
RETURN
END IF
(4)获取request传入参数内容
#############################################
# 描述……:获取request传入参数内容
# 备注……:
# 输入参数:p_json_obj:要获取的参数record
# 返回代码……:TRUE/FALSE:Boolean,执行是否成功
# :l_json_req_parm:JSONObject,request参数内容
#############################################
PUBLIC FUNCTION cl_ws_api_get_param(p_json_obj)
DEFINE p_json_obj util.JSONObject #要获取的参数record
DEFINE l_json_req_parm util.JSONObject #request参数内容
DEFINE ls_jsonobj STRING
INITIALIZE l_json_req_parm TO NULL
# 依xml,json格式个别处理,获取参数内容
CASE g_content_type
WHEN "1" #XML格式
#解析JSONObject,获取XML简单结构parameter参数资料
LET l_json_req_parm = cl_ws_api_get_xml_param(p_json_obj)
exit case
WHEN "2" #JSON格式
#延用已有的function获取jsonObject "parameter"参数
LET l_json_req_parm = cl_aws_json_getParam()
exit case
OTHERWISE
INITIALIZE g_errparam TO NULL
LET g_errparam.code = "lib-00448" #无法识别内容格式(g_content_type)
LET g_errparam.popup = FALSE
DISPLAY "error:无法识别内容格式(g_content_type),请确认传入格式!"
RETURN FALSE, l_json_req_parm
END CASE
IF (g_json_datetype.getLength() > 0) AND (l_json_req_parm IS NOT NULL) THEN
# 有栏位要转换日期格式
LET ls_jsonobj = cl_aws_json_dateformat(l_json_req_parm.toString(),"OBJECT","","parameter")
LET l_json_req_parm = util.JSONObject.parse(ls_jsonobj)
END IF
#
RETURN TRUE, l_json_req_parm
END FUNCTION
(5)常用方法举例
- cl_aws_json_getValue()
取得字段值 - cl_aws_json_getParam()
取得整个param段 - l_json_obj.toFGL()
将param段的数据转换读取到预定义变量 - cl_aws_json_addParam(util.JSONObject.fromFGL(l_return))
将返回变量自动加入response的json中
(6)业务逻辑
在进行具体的业务逻辑时,可能需要引入工具类等类库,需要在这个部分进行引入
例如添加一个util
工具类
IMPORT os
IMPORT xml
#add-point:增加导入项目 name="global.import"
import util
#end add-point
具体编写业务逻辑的代码,可以放在这个部分中
例如获取数据,设定报错内容等:
PRIVATE FUNCTION cwssp419_process() RETURNS () #200213-00032
#add-point: 服务逻辑主要处理段的ADP name="cwssp419.process"
DEFINE l_json_obj util.JSONObject
TYPE type_header RECORD
imaa001 LIKE imaa_t.imaa001
END RECORD
TYPE type_detail RECORD
imae001 LIKE imae_t.imae001
END RECORD
DEFINE param RECORD
imaaheader type_header,
imaadetail DYNAMIC ARRAY OF type_detail
END RECORD
DEFINE r_return RECORD
code1 LIKE type_t.chr10
END RECORD
LET l_json_obj = cl_aws_json_getParam()
# 获取传入的数据到param中
IF l_json_obj IS NULL THEN
INITIALIZE g_errparam TO NULL
LET g_errparam.code = "wss-00216" #读入json 发生问题
LET g_errparam.extend = ''
CALL cl_err()
RETURN
END IF
#由JSONObject 转入Record
CALL l_json_obj.toFGL(param)
LET g_status.code = "!"
LET g_status.description = "报错内容!"
CALL cl_aws_json_addParam(util.JSONObject.fromFGL(r_return))
#end add-point
END FUNCTION
上传代码并请求后的结果如下,可以看到输出的提示已经变成了设定好的内容。
(7)报错编码
报错编码都存放在azzi920
这个作业中,如下图所示:
8、接口调试
方法一
可以直接在awsq990
中,针对某一个服务进度debug
,也可以在查询对应的接口请求信息后,选中某个记录进行debug
。
方法二
每天请求的文件都存放在请求的日志文件中,可以打开日志文件进行查看
首先在Xshell
中进入tmp
文件夹
cd tmp
然后进入当天的日期文件夹
cd 日期 //如:20250507
然后输入ls
,可以查看所有的请求日志
如果当天的接口请求记录较多,无法直接进行区分的话,进行可以根据接口请求的时间戳,进行查询
grep -n "20151211123204361" ./*
查询结果如下,可以看到文件名称就出来了
确定好日志文件后,我们进入到log文件夹,将这个文件进行打开
# 进入log文件夹
cd log
# 打开文件
grep -n "http_req_10:48:51.895_F645998B-4568-4206-A674-2C797031314D.xml" ./*
打开后界面如下,然后复制红色框起来的内容,后续需要执行debug
命令
然后进入到4gl
的目录下。这一步需要注意,如果这个接口是客制的,那么是cwss
,如果不是客制的,是在wss
文件夹下。
cd cwss/4gl
可以在azzi700
中进行区分,是否为客制。客制框勾选则为客制接口,否则为非客制接口。
进入文件夹后,直接输入刚刚复制的命令即可
r.dg cwssp419 '/ut/toptst/tmp/20250507/http_req_10:48:51.895_F645998B-4568-4206-A674-2C797031314D.xml'
随后会弹出Debug
的窗口
唤出debug
界面后,可以在需要进行调试的部分打上断点。具体的调试步骤与其他工具调试方法类似。
如果需要监视某个参数的值,可以点击debug
页面上方的inspect
按钮,在输入框中输入需要监视的参数,然后继续调试即可
常见的debug操作说明
如果需要传输文件的话,需要将文件转换成base64文件流的形式进行传输
二、T100作为客户端
请求外部的接口,需要根据对方的API格式进行请求,下面为请求范例。
PUBLIC FUNCTION cs_erp_http_req(p_req_url,p_pos_param)
DEFINE req com.HTTPRequest
DEFINE resp com.HTTPResponse
DEFINE p_req_url STRING
DEFINE p_pos_param STRING
DEFINE l_str STRING
#LET p_req_url = p_req_url,"?id=",p_pos_param
DISPLAY 'URL:',p_req_url
LET req = com.HTTPRequest.Create(p_req_url)
#设置请求格式,包括请求头,数据格式,请求方法等
#CALL req.setHeader("Content-Type","application/json")
CALL req.setCharset("UTF-8")
CALL req.setHeader("ContentLength", p_pos_param.getLength())
#CALL req.setHeader("ContentLength", 20000)
CALL req.setMethod("POST")
CALL req.doTextRequest(p_pos_param)
CALL req.setConnectionTimeOut(120)
LET resp = req.getResponse()
#获取发送请求后服务器返回的状态码, 200为正常访问
IF resp.getStatusCode() != 200 THEN
DISPLAY "HTTP Error (" || resp.getStatusCode() || ") ", resp.getStatusDescription()
ELSE
#获取请求返回的json字符串
LET l_str = resp.getTextResponse()
END IF
RETURN l_str
END FUNCTION