4gl调用WEB API,实现JSON传递(Demo)_4gl json

测试环境: GP5.25 , fjs版本2.32,解析json所需要的jar依赖包 (PS: 如果没有记错是fjs2.32版本及以上才支持java bridge,所以GP 5.25以下的同学就不要用这种方式去测试)

测试内容: 利用此fjs版本对java bridge的支持,实现4gl调用WEB API,实现json传递 

测试步骤如下:

1.下载本次测试需要的jar依赖包,百度搜索就有 “Java 解析JSON,JSON-LIBjar包下载”。只是if-common.jar文件要稍微注意,这是别人写好的包,下载下来是没有的。(如果有java经的童鞋,想一下就知道这里面会写什么)


2.将下载的jar文件传到ERP服务器对应的目录:/u1/topprod/tiptop/ds4gl2/bin/javaad/jar。

3.修改环境变量 tiptop_env文件中的jar包引用路径。

tiptop_env位置:/u1/topprod/tiptop/bin/tiptop_env,

可使用VI直接进行编辑,然后保存。(注意:多个环境变量以 冒号 隔开,最后一个环境变量时用 分号 结束)

4.编写4gl代码,重点将上传到服务器中的jar包,通过import方式导入到4gl代码中,以便调用。(目前已写成公共函数放lib/cl_web_api.4gl)

基本思路:将URL及要传递的JSON格式数据作为参数传入接口,将接口返回的数据/对象进行解析,存入一个随机创建的临时表(随机:表名不会重复,临时表为会话类型),回传给4gl临时表,供4gl再次处理。

4gl调用此lib,参数3传入不同的值,会有两种回传结果: 1.返回临时表名2.返回对象。

 

5.<第一种:返回临时表名>

调用lib下的方法CALLcl_web_api(p_Url,p_Post_Json,p_Type,p_Nouse2),

设置第三个参数p_Type = 1, 返回临时表名,临时表内容为API接口返回的JSON数据,程序调用示例:

 

 根据回传的表名做一个简单的FOREACH测试:

 

6.<第二种:返回对象>

调用lib下的方法CALLcl_web_api(p_Url,p_Post_Json,p_Type,p_Nouse2),

设置第三个参数p_Type = 2, 返回临对象,程序调用示例:

  

7.有个前提很重要,如果是要访问外部的WEB API接口,ERP服务器要一定可以访问外网;当然如果不方便让ERP服务器访问外网,就调用局域网下发布WEB API接口也是可以的。

                                              Author : Kellan

                                                Q Q :   309200966

                                                          Date:  2018年3月26日11:32:49

干货奉送!!!  cl_web_api.4gl源码如下:

  1. `
  2. # Prog. Version..: '5.25.11-12.12.11(00010)' #
  3. #<-------------------------------------------------------------------------------------------------------------->
  4. # Library name.....: cl_web_api.4gl
  5. # Descriptions.....: 4GL提交Json到Web,获取Web返回的对象,并进行解析.(4GL调用外部Web API)
  6. # Memo.............: Two days,so funny. Where there is a will,there is a way..Ha-Ha-Ha..
  7. # Usage............: CALL cl_web_api(p_Url,p_Post_Json,p_Type,p_Nouse2) RETURNING p_Temp_Tab/object
  8. # param_In_1.......: p_Url , type=String
  9. # <--Example-->: p_Url = "http://xxx.xxx.x.xx/2wm/public/index.php/api/Index/uploadTest?a=test"
  10. # param_In_2.......: p_Post_Json , type=String
  11. # <--Example-->: p_Post_Json = 'postData=[{"rec_id": "1","name": "匡奎"},{"rec_id": "2","name": "李聚"}]'
  12. # param_In_3.......: p_Type , type= Integer (type = 1 返回表名 type = 2 返回对象 )
  13. # param_In_4.......: p_Nouse2 , type=String
  14. #
  15. # param_Out_1......: p_Temp_Tab, type = String, Create temp table with random.
  16. #
  17. # Date & Authors...: 2018-03-23/24 By Kellan & Andrew
  18. #<-------------------------------------------------------------------------------------------------------------->
  19. IMPORT os
  20. IMPORT com
  21. IMPORT JAVA net.sf.json.JSON
  22. IMPORT JAVA net.sf.json.JSONArray
  23. IMPORT JAVA net.sf.json.JSONObject
  24. IMPORT JAVA com.lifesense.common.HttpUtils
  25. IMPORT util
  26. DATABASE ds
  27. GLOBALS "../../config/top.global"
  28. FUNCTION cl_web_api(p_Url,p_Post_Json,p_Type,p_Nouse2)
  29. DEFINE p_Url STRING,
  30. p_Post_Json STRING,
  31. p_Type INTEGER ,
  32. p_Nouse2 STRING
  33. DEFINE l_rData STRING,
  34. l_i INTEGER,
  35. l_i_i INTEGER
  36. DEFINE w net.sf.json.JSONObject #获取接口回传的对象
  37. DEFINE jsony,jsonykey net.sf.json.JSONArray
  38. DEFINE jsonwx net.sf.json.JSONObject
  39. DEFINE l_str STRING
  40. DEFINE l_tab_colum STRING,
  41. l_tem_tab_name STRING,
  42. l_json_values STRING,
  43. l_ins_values STRING
  44. DEFINE l_ins_sql STRING,
  45. l_msg STRING
  46. #组合URL,提交参数的JSON格式,返回对象 w
  47. LET l_tab_colum = " "
  48. LET g_success = 'Y'
  49. TRY
  50. CALL HttpUtils.getJSONObject(p_Url,p_Post_Json) RETURNING w
  51. CATCH
  52. LET l_msg = "ERROR :",STATUS,"==>API接口通讯失败!"
  53. CALL cl_err(l_msg,"!",1)
  54. IF p_Type = 1 THEN
  55. RETURN " "
  56. ELSE
  57. RETURN w
  58. END IF
  59. END TRY
  60. IF p_Type = 2 THEN
  61. RETURN w
  62. END IF
  63. #web端固定回传对象为rData
  64. LET l_rData = w.getString("rData")
  65. CALL cl_err(l_rData,'!',1)
  66. #根据回传对象rData解析为数组
  67. LET jsony = w.getJSONArray("rData")
  68. IF jsony.size()=0 THEN
  69. CALL cl_err("获取回传值失败!",'!',1)
  70. RETURN " "
  71. END IF
  72. #begin----------------------------------create temp table------------------------------------------
  73. #循环json的key值作为字段创建一个临时表:l_tem_tab_name.临时表字段统一用varhcar(4000)顶额
  74. LET jsonwx = JSONObject.fromObject(jsony.getString(0))
  75. LET jsonykey = jsonwx.names() #json key获取 array
  76. FOR l_i_i = 0 TO jsonykey.size()-1
  77. IF cl_nvl(jsonykey.getString(l_i_i)," ") = " " THEN
  78. CALL cl_err("服务器回传的JSON格式key值为空,这是不允许的!","!",1)
  79. LET g_success = 'N'
  80. EXIT FOR
  81. END IF
  82. LET l_tab_colum = l_tab_colum,' ',
  83. jsonykey.getString(l_i_i),' VARCHAR(4000)',','
  84. END FOR
  85. IF g_success = 'N' THEN
  86. RETURN " "
  87. END IF
  88. CALL cl_operation_str(l_tab_colum) RETURNING l_tab_colum
  89. CALL cl_create_temp_table(l_tab_colum) RETURNING l_tem_tab_name
  90. IF cl_nvl(l_tem_tab_name," ") = " " THEN
  91. RETURN " "
  92. END IF
  93. #end----------------------------------create temp table------------------------------------------
  94. #begin----------------------------------insert data into temp table------------------------------
  95. #两层循环,获取key对应的value值:l_values,组合出插入临时表的value值('column1','column2'.......),并写入临时表
  96. FOR l_i = 0 TO jsony.size()-1
  97. LET jsonwx = JSONObject.fromObject(jsony.getString(l_i))
  98. LET jsonykey = jsonwx.names() #json key获取 array
  99. LET l_ins_values = " "
  100. LET l_json_values = " "
  101. FOR l_i_i = 0 TO jsonykey.size()-1
  102. LET l_json_values = jsonwx.getString(jsonykey.getString(l_i_i)) #根据json key 获取对应的value
  103. IF cl_nvl(l_json_values," ") = " " THEN
  104. LET l_json_values = " "
  105. END IF
  106. LET l_ins_values = l_ins_values," ","'",l_json_values,"'","," #json key对应的values可能有特殊符号待处理?
  107. END FOR
  108. CALL cl_operation_str(l_ins_values) RETURNING l_ins_values
  109. LET l_ins_sql = " INSERT INTO ",l_tem_tab_name," ",
  110. " VALUES ",l_ins_values
  111. PREPARE l_ins_sql_pb FROM l_ins_sql
  112. EXECUTE l_ins_sql_pb
  113. IF STATUS THEN
  114. CALL cl_err("写入临时表失败!","1",1)
  115. RETURN " "
  116. END IF
  117. END FOR
  118. #end----------------------------------insert data into temp table------------------------------
  119. RETURN l_tem_tab_name
  120. END FUNCTION
  121. FUNCTION cl_create_temp_table(p_tab_colum)
  122. DEFINE p_tab_colum STRING
  123. DEFINE l_cre_temp_tab_sql STRING,
  124. l_tab_name STRING,
  125. l_random INTEGER,
  126. l_ymd VARCHAR(20),
  127. ls_time STRING
  128. CALL util.Math.rand(10000) RETURNING l_random
  129. LET ls_time = TIME
  130. LET l_tab_name = g_prog CLIPPED, "_",
  131. TODAY USING "YYMMDD", "_",
  132. ls_time.subString(1,2), ls_time.subString(4,5), ls_time.subString(7,8),'_',l_random
  133. CALL cl_replace_str(l_tab_name,' ','') RETURNING l_tab_name
  134. LET l_cre_temp_tab_sql = " Create Global Temporary Table ", #两种方式创建临时表1,会话类型;2,事务类型
  135. " ",l_tab_name," ",
  136. " ",p_tab_colum," On Commit Preserve Rows " #本次选择会话类型创建
  137. PREPARE l_cre_temp_tab_pb FROM l_cre_temp_tab_sql
  138. EXECUTE l_cre_temp_tab_pb
  139. IF STATUS THEN
  140. CALL cl_err("创建临时表出错"||l_tab_name,'!',1)
  141. RETURN " "
  142. END IF
  143. RETURN l_tab_name
  144. END FUNCTION
  145. FUNCTION cl_operation_str(p_str)
  146. DEFINE p_str STRING
  147. LET p_str = p_str.substring(3,length(p_str)) #去掉开头的空格
  148. LET p_str = p_str.substring(1,length(p_str)-1) #去掉最后一个逗号
  149. LET p_str = '(',p_str,')' #外层加上括号
  150. RETURN p_str
  151. END FUNCTION