PeopleSoft-如何在PS系统中使用腾讯COS服务做文件服务器

前言

​ 本文主要介绍如何使用腾讯COS服务作为PeopleSoft系统的文件服务器,其中【上传】主要涉及到文件临时存储在PS服务器上,然后再通过腾讯的Java-jdk将服务器上的临时文件转存到COS服务中,【下载】则反之。

根据腾讯COS-Java-JDK进行连通性测试

将JDK改造为使用的方式,打成jar包,引入PS系统中,在系统中调用即可。

文件上传PS服务器(临时文件)

首先在服务器创建临时文件的文件夹,然后进行对应的授权,同时开通Linux服务器的SFTP功能;

在PS页面进行SFTP URL的配置

然后使用PS标准的功能附件上传功能测试工具进行测试

成功后,检查服务器上是否有刚刚上传的文件;同时测试一下,下载,删除功能。

创建方法定义WORK表

上传代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
Declare Function add_attachment PeopleCode FILE_ATTACH_WRK.ATTACHADD FieldChange;
Declare Function delete_attachment PeopleCode FILE_ATTACH_WRK.ATTACHDELETE FieldChange;

/*******************************************************************************************
* 工程:C_JT_HR_95
* 功能:1、利用系统标准功能,将文件上传至FSTP文件服务器(临时);
2、利用腾讯提供的SDK,将文件从FSTP文件服务器上传至腾讯COS中,
同时,清除FSTP文件服务器中的临时文件;

注意:如果应用服务器重启,会导致腾讯的SDK中的Java报异常,这个需要后期腾讯处理;
目前解决方案是:重启后连续上传两次失败后,后续上传即可成功!
(已经处理,是log4j类在虚拟机中加载顺序导致的问题,只需要把log4j类的引用去除掉就好)
=============================================================================================
* 作者 时间 操作
* GEK 2021-06-07 新增
********************************************************************************************/

Function c_add_attachment(&FSTP_URL_ID, &FSTP_URL_PATH_ID) Returns array of string
/****************************************************************************************
* 入参数: &FSTP_URL_ID -- FSTP服务器的地址(前缀为FSTP:); *
* &FSTP_URL_PATH_ID -- FSTP临时文件夹的路径; *
* 出参数: array of string -- 一维数组 *
* 1号位,结果状态,1表示成功;0表示失败;2表示取消 *
* 2号位,系统唯一文件名; *
* 1号位,用户文件名; *
***************************************************************************************/

/* 如果不传FSTP的ID时,默认使用 C_SFTP_URL */
If &FSTP_URL_ID = "" Then
&FSTP_URL_ID = "C_SFTP_URL";
End-If;
/* 如果不传FSTP的文件路径时,默认使用 C_SFTP_URL_PATH */
If &FSTP_URL_PATH_ID = "" Then
&FSTP_URL_PATH_ID = "C_SFTP_URL_PATH";
End-If;

Local string &strATTACHSYSFILENAME, &strATTACHUSERFILE; /*定义参数;1、系统唯一文件名;2、用户上传文件名*/
Local array of string &retArrOfString = CreateArrayRept("", 0); /*创建一个返回数组*/

/* 定义LOG日志 */
Local string &sysFileName = "tencenCOS.log";
&fileLog = GetFile(GetURL(URL.C_TEMP_FILE_PATH) | "LOGS/" | &sysFileName, "A", "UTF8", %FilePath_Absolute);
&fileLog.WriteLine("Begin ***** Datetime=" | %Datetime);

/*生成UUID,唯一文件名前缀*/
&strATTACHSYSFILENAME = UuidGen();

add_attachment("URL." | &FSTP_URL_ID, &FILEEXTENSION, &SUBDIRECTORY, &FILESIZE, True, &recname, &strATTACHSYSFILENAME, &strATTACHUSERFILE, &MESSAGE_LVL, &RETCODE);
rem WinMessage("&RETCODE=" | &RETCODE);
/* 返回0表示上传FSTP服务器成功,其他数字表示失败 */
If &RETCODE = 0 Then
try
/* 获取文件在FSTP服务器中的绝对路径 */
Local string &serFilePath = GetURL(@("url." | &FSTP_URL_PATH_ID)) | &strATTACHSYSFILENAME;
/* 生成腾讯标准SDK中的文件操作Java对象 */
Local JavaObject &fileOperator = CreateJavaObject("com.qcloud.cos.demo.FileOperatClass");
/* 将FSTP服务器中的文件上传到腾讯COS */
&fileLog.WriteLine("&serFilePath=" | &serFilePath);
Local string &strReturn = &fileOperator.AppendObjectFromLocal(&strATTACHSYSFILENAME, &serFilePath);
/* 返回值如果可以转换为数组,且大于零,即上传文件的字节数,表示上传成功 */
If Value(&strReturn) > 0 Then
/* 在用户上传文件记录表中记录 */
Local Record &recC_USER_FILE_TBL = CreateRecord(Record.C_USER_FILE_TBL);
&recC_USER_FILE_TBL.ATTACHSYSFILENAME.Value = &strATTACHSYSFILENAME;
&recC_USER_FILE_TBL.C_USER_FILENAME.Value = &strATTACHUSERFILE;
&recC_USER_FILE_TBL.LASTUPDDTTM.Value = %Datetime;
&recC_USER_FILE_TBL.LASTUPDOPRID.Value = %UserId;
&recC_USER_FILE_TBL.Insert();
/* 将系统唯一文件名、用户文件名插入返回数组,2、3位 */
&retArrOfString.Push("1");
&retArrOfString.Push(&strATTACHSYSFILENAME);
&retArrOfString.Push(&strATTACHUSERFILE);
/* 删除FSTP文件服务器中的临时文件 */
Local string &strATTACHSYSFILENAME1 = &strATTACHSYSFILENAME;
delete_attachment("URL." | &FSTP_URL_ID, &strATTACHSYSFILENAME, &strATTACHUSERFILE, &MESSAGE_LVL, &RETCODE);
&fileLog.WriteLine("cosKey=" | &strATTACHSYSFILENAME1 | ",上传成功 ");
MessageBox(0, "", 20000, 51, "Message Not Found", "", "成功!");
Else
/* 返回数组, 1号位传0表示失败*/
&retArrOfString.Push("0");
&fileLog.WriteLine("Java返回&strReturn=" | &strReturn | ",cosKey=" | &strATTACHSYSFILENAME | ",上传失败!");
MessageBox(0, "", 20000, 51, "Message Not Found", "由于网络原因,", "失败,请重试!");
End-If;
catch Exception &e
/* 捕捉java在服务器重启后报错的异常*/
&retArrOfString.Push("0");
&fileLog.WriteLine("cosKey=" | &strATTACHSYSFILENAME | ",上传失败,exception =" | &e.ToString());
MessageBox(0, "", 20000, 51, "Message Not Found", "由于网络原因,", "失败,请重试!");
end-try;
End-If;

If &RETCODE = 2 Or
&RETCODE = 0 Then
/*
0 - 上传成功;
2 - 取消上传;
*/
If &RETCODE = 2 Then
&retArrOfString.Push("2");
End-If;

Else
/*
记录上传FSTP中的报错;
*/
/* 返回数组, 1号位传0表示失败*/
&retArrOfString.Push("0");
&fileLog.WriteLine("PS返回&RETCODE=" | &RETCODE | ",cosKey=" | &strATTACHSYSFILENAME | ",上传失败!");
MessageBox(0, "", 20000, 51, "Message Not Found", "由于网络原因,", "失败,请重试!");
End-If;

/*日志结束*/
&fileLog.WriteLine("End ***** Datetime=" | %Datetime);
&fileLog.WriteLine(" ");
&fileLog.WriteLine(" ");
&fileLog.close();

Return &retArrOfString;

End-Function;


下载代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
Declare Function detach_attachment PeopleCode FILE_ATTACH_WRK.ATTACHDET FieldChange;
Declare Function delete_attachment PeopleCode FILE_ATTACH_WRK.ATTACHDELETE FieldChange;

/*******************************************************************************************
* 工程:C_JT_HR_95
* 功能:1、利用腾讯提供的SDK,将文件从腾讯COS中下载至FSTP文件服务器;
2、利用系统标准功能,将文件从FSTP文件服务器(临时)中下载到本地,
同时,清除FSTP文件服务器中的临时文件;

注意:如果应用服务器重启,会导致腾讯的SDK中的Java报异常,这个需要后期腾讯处理;
目前解决方案是:重启后连续上传两次失败后,后续上传即可成功!
(已经处理,是log4j类在虚拟机中加载顺序导致的问题,只需要把log4j类的引用去除掉就好)
=============================================================================================
* 作者 时间 操作
* GEK 2021-06-07 新增
********************************************************************************************/

Function c_dow_attachment(&FSTP_URL_ID, &FSTP_URL_PATH_ID, &strATTACHSYSFILENAME) Returns string
/*******************************************************************************
* 入参数: &FSTP_URL_ID -- FSTP服务器的地址(前缀为FSTP:); *
* &FSTP_URL_PATH_ID -- FSTP临时文件夹的路径; *
* &strATTACHSYSFILENAME -- 系统唯一文件名; *
* &strC_USER_FILENAME -- 用户文件名; *
* 出参数: string -- 方法结果:1表示成功,2表示失败; *
*******************************************************************************/

/* 如果不传FSTP的ID时,默认使用 C_SFTP_URL */
If &FSTP_URL_ID = "" Then
&FSTP_URL_ID = "C_SFTP_URL";
End-If;
/* 如果不传FSTP的文件路径时,默认使用 C_SFTP_URL_PATH */
If &FSTP_URL_PATH_ID = "" Then
&FSTP_URL_PATH_ID = "C_SFTP_URL_PATH";
End-If;


/* 日志记录 */
Local string &sysFileName = "tencenCOS.log";
&fileLog = GetFile(GetURL(URL.C_TEMP_FILE_PATH) | "LOGS/" | &sysFileName, "A", "UTF8", %FilePath_Absolute);
&fileLog.WriteLine("Begin ***** Datetime=" | %Datetime);

try
Local string &strDelRet; /* 返回参数 */

/* 获取文件在FSTP文件服务器中的绝对路径*/
Local string &serFilePath = GetURL(@("url." | &FSTP_URL_PATH_ID)) | &strATTACHSYSFILENAME;
/* 生成腾讯标准SDK中的文件操作Java对象 */
Local JavaObject &fileOperator = CreateJavaObject("com.qcloud.cos.demo.FileOperatClass");
/* 利用腾讯提供的SDK,将文件从腾讯COS中下载至FSTP文件服务器 */
Local string &strReturn = &fileOperator.GetObjectToFileDemo(&strATTACHSYSFILENAME, &serFilePath);
If &strReturn = "true" Then

/* 根据系统唯一文件名获取用户文件名 */
Local string &strC_USER_FILENAME = "";
Local Record &recC_USER_FILE_TBL = CreateRecord(Record.C_USER_FILE_TBL);
&recC_USER_FILE_TBL.ATTACHSYSFILENAME.Value = &strATTACHSYSFILENAME;
If &recC_USER_FILE_TBL.SelectByKey() Then
&strC_USER_FILENAME = &recC_USER_FILE_TBL.C_USER_FILENAME.Value
Else
&strC_USER_FILENAME = "未知文件";
End-If;

/* 利用系统标准功能,将文件从FSTP文件服务器(临时)中下载到本地 */
detach_attachment("URL." | &FSTP_URL_ID | "", &strATTACHSYSFILENAME, &strC_USER_FILENAME, &MESSAGE_LVL, &RETCODE);

If &RETCODE = 0 Then
rem MessageBox(0, "", 20000, 52, "Message Not Found", "成功");
/* 清除FSTP文件服务器中的临时文件 */
delete_attachment("URL." | &FSTP_URL_ID | "", &strATTACHSYSFILENAME, &strC_USER_FILENAME, &MESSAGE_LVL, &RETCODE);
&strDelRet = "1";
&fileLog.WriteLine("cosKey=" | &strATTACHSYSFILENAME | ",下载成功");
Else
&strDelRet = "0";
&fileLog.WriteLine("PS返回&RETCODE=" | &RETCODE | ",cosKey=" | &strATTACHSYSFILENAME | ",下载失败!");
MessageBox(0, "", 20000, 52, "Message Not Found", "由于网络原因,", "失败,请重试!");
End-If;
Else
&strDelRet = "0";
&fileLog.WriteLine("Java返回&strReturn=" | &strReturn | ",cosKey=" | &strATTACHSYSFILENAME | ",下载失败!");
MessageBox(0, "", 20000, 52, "Message Not Found", "由于网络原因,", "失败,请重试!");
End-If;
catch Exception &e
&strDelRet = "0";
&fileLog.WriteLine("cosKey=" | &strATTACHSYSFILENAME | ",下载失败,exception =" | &e.ToString());
MessageBox(0, "", 20000, 52, "Message Not Found", "由于网络原因,", "失败,请重试!");
end-try;

/*日志结束*/
&fileLog.WriteLine("End ***** Datetime=" | %Datetime);
&fileLog.WriteLine(" ");
&fileLog.WriteLine(" ");
&fileLog.close();

Return &strDelRet;

End-Function;


删除代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
/*******************************************************************************************
* 工程:C_JT_HR_95
* 功能:1、利用腾讯提供的SDK,将文件腾讯COS中删除;

注意:如果应用服务器重启,会导致腾讯的SDK中的Java报异常,这个需要后期腾讯处理;
目前解决方案是:重启后连续上传两次失败后,后续上传即可成功!
(已经处理,是log4j类在虚拟机中加载顺序导致的问题,只需要把log4j类的引用去除掉就好)
=============================================================================================
* 作者 时间 操作
* GEK 2021-06-07 新增
********************************************************************************************/

Function c_del_attachment(&strATTACHSYSFILENAME) Returns string
/******************************************************************************
* 入参数: &strATTACHSYSFILENAME -- 系统唯一文件名; *
* *
* 出参数: string -- 方法结果:1表示成功,2表示失败; *
* *
******************************************************************************/

/*日志记录*/
Local string &sysFileName = "tencenCOS.log";
&fileLog = GetFile(GetURL(URL.C_TEMP_FILE_PATH) | "LOGS/" | &sysFileName, "A", "UTF8", %FilePath_Absolute);
&fileLog.WriteLine("Begin ***** Datetime=" | %Datetime);


/* 生成腾讯标准SDK中的文件操作Java对象 */
Local JavaObject &fileOperator = CreateJavaObject("com.qcloud.cos.demo.FileOperatClass");
try
Local string &strDelRet; /* 返回参数 */

/* 调用腾讯标准SDK删除腾讯COS中的文件 */
Local string &strReturn = &fileOperator.DelSingleFile(&strATTACHSYSFILENAME);

If &strReturn = "true" Then
/* 删除 用户上传腾讯COS文件服务器记录表 中对应的数据*/
Local Record &recC_USER_FILE_TBL = CreateRecord(Record.C_USER_FILE_TBL);
&recC_USER_FILE_TBL.ATTACHSYSFILENAME.Value = &strATTACHSYSFILENAME;
If &recC_USER_FILE_TBL.SelectByKey() Then
&recC_USER_FILE_TBL.Delete();
End-If;
&strDelRet = "1";
&fileLog.WriteLine("cosKey=" | &strATTACHSYSFILENAME | ",删除成功!");
MessageBox(0, "", 20000, 53, "Message Not Found", "", "成功!");
Else
&strDelRet = "0";
&fileLog.WriteLine("Java返回&strReturn=" | &strReturn | ",cosKey=" | &strATTACHSYSFILENAME | ",删除失败!");
MessageBox(0, "", 20000, 53, "Message Not Found", "由于网络原因,", "失败,请重试!");
End-If;

catch Exception &e
&strDelRet = "0";
&fileLog.WriteLine("cosKey=" | &strATTACHSYSFILENAME | ",删除失败,exception =" | &e.ToString());
MessageBox(0, "", 20000, 53, "Message Not Found", "由于网络原因,", "失败,请重试!");
end-try;

/*日志结束*/
&fileLog.WriteLine("End ***** Datetime=" | %Datetime);
&fileLog.WriteLine(" ");
&fileLog.WriteLine(" ");
&fileLog.close();

Return &strDelRet;

End-Function;


定义一张文件上传记录表

用来记录用户上传的文件唯一编码值,文件真实名称,同时记录上次操作者、操作时间。

每个附件在需要增加文件的表中增加一个字段用来记录文件唯一编码值,然后根据该唯一编码值来寻找文件真实名称;同时根据记录表中存在的唯一编码值来确定该文件是否被删除了;因为PS页面存在缓存机制,例如,用户可以在页面点击删除文件,然后此时需要调用相关的代码操作腾讯COS, 该调用过程不可逆,但是,用户却可以选择不保存本次修改的页面;所以,此时需要在点击【删除】按钮时提示用户,该过程不可逆,同事删除掉记录表中的唯一编码值。等用户再次进来时,需要判断目前页面中的附件唯一文件名是否存在于记录表中,如不存在,表示该附件已经被删除。(这种情况一般出现在用户必须上传附件才能保存,但是此时用户删除了附件,即使同时调用dosave()方法也是无法保存的。一般情况下,不管上传还是下载,我们都是在按钮的最后执行Dosave()方法。)

注意:这张记录表可以考虑跑进程定时清理垃圾数据,通过【实际存储文件唯一编码字段】中的值同【文件上传记录表】的记录进行对比,可以查出那些事垃圾数据,然后进行清理。

<img src=PeopleSoft-如何在PS系统中使用腾讯COS服务做文件服务器/20210620174447.png”/>

页面使用文件功能

页面

调用代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//进入页面初始化
/*根据是有都附件控制按钮是否可以点击*/
If All(C_PRH_CONTR_TBL.C_FILE_PATH1.Value) Then
C_PRH_CONTR_TBL.C_ADD_BUTTON1.DisplayOnly = True;
C_PRH_CONTR_TBL.C_DEL_BUTTON1.DisplayOnly = False;
C_PRH_CONTR_TBL.C_DOW_BUTTON1.DisplayOnly = False;
Else
C_PRH_CONTR_TBL.C_ADD_BUTTON1.DisplayOnly = False;
C_PRH_CONTR_TBL.C_DEL_BUTTON1.DisplayOnly = True;
C_PRH_CONTR_TBL.C_DOW_BUTTON1.DisplayOnly = True;
End-If;

//上传
Declare Function c_add_attachment PeopleCode C_USER_FILE_WRK.ATTACHADD FieldFormula;
Local array of string &retArrOfString = c_add_attachment("", "");
If &retArrOfString [1] = "1" Then
C_PRH_CONTR_TBL.C_FILE_PATH1.Value = &retArrOfString [2];
C_PRH_CONTR_TBL.C_ADD_BUTTON1.DisplayOnly = True;
C_PRH_CONTR_TBL.C_DEL_BUTTON1.DisplayOnly = False;
C_PRH_CONTR_TBL.C_DOW_BUTTON1.DisplayOnly = False;
DoSave();
End-If;

//删除
Declare Function c_del_attachment PeopleCode C_USER_FILE_WRK.ATTACHDELETE FieldFormula;
/* 用户确认删除 */
Local number &retMsg = MessageBox(1, "", 20000, 57, "Message Not Found");
If &retMsg = 1 Then
Local string &retString = c_del_attachment(C_PRH_CONTR_TBL.C_FILE_PATH1.Value);
If &retString = "1" Then
C_PRH_CONTR_TBL.C_FILE_PATH1.Value = "";
C_PRH_CONTR_TBL.C_ADD_BUTTON1.DisplayOnly = False;
C_PRH_CONTR_TBL.C_DEL_BUTTON1.DisplayOnly = True;
C_PRH_CONTR_TBL.C_DOW_BUTTON1.DisplayOnly = True;
DoSave();
End-If;
End-If;

//下载
Declare Function c_dow_attachment PeopleCode C_USER_FILE_WRK.ATTACHDET FieldFormula;
Local string &strATTACHSYSFILENAME = C_PRH_CONTR_TBL.C_FILE_PATH1.Value;
Local string &retString = c_dow_attachment("", "", &strATTACHSYSFILENAME);

Q&A

Q1.如果应用服务器重启,会导致腾讯的SDK中的Java报异常,这个需要后期腾讯处理;

​ A1.已经处理。是log4j类在虚拟机中加载顺序导致的问题,只需要把log4j类的引用去除掉就好。