一、需求背景
在PS开发中经常需要与第三方系统进行文件传输,例如在某项目中,员工离职需要根据模板生成员工离职证明,然后将离职证明发送到第三方系统进行盖章,第三方系统会返回盖完章后的离职证明地址,PS需要将盖章后的离职证明保存一份到PS系统。
二、解决方案
以前PS实现文件下载有以下种方式:
实现方式 | 优点 | 缺点 |
第三方Jar包 | 这种方式实现比较简单,大部分代码在Java端写,PS只需要调用Jar包提供的方法即可。 | PS没有良好的Jar包管理工具,经常会导致相同的Jar包反复上传。其次需要服务器权限,有些申请服务器权限很麻烦。 |
传输Base64 | PS可以借助IB来实现,不需要使用到Java。 | Base64有体积膨胀的问题,例如一个1M的文件经过Base64编译后会变成1.3M左右。 |
现在新增了两种实现方式:
实现方式 | 优点 | 缺点 |
原生Java类 | 不需要服务器权限,使用原生Java类实现,不用担心Jar包冲突问题。 | 尚未经过大量测试。 |
配置MTOM传输 | 官方推荐的方式,我没有配置成功,不过多评价 |
三、实现方式
这次是采用原生Java类的方式去实现的。
核心代码:
/*========================================================== 函数名 : getAttachmentFromOtherSystem 说明 : 从第三方系统下载附件 输入参数: &url 附件资源路径 &headers 请求头参数 输出参数: 文件在服务器中的绝对路径 ---------------------------------------------------------- 日期 作者 BUG编号 修改历史 2023/01/31 kqs 创建 ===========================================================*/ Function getAttachmentFromOtherSystem(&url As string, &headers As JsonObject) Returns string Local string &dirPath = "/tmp/files/"; If Not FileExists(&dirPath, %FilePath_Absolute) Then CreateDirectory(&dirPath, %FilePath_Absolute); End-If; Local string &fileName = UuidGen(); Local string &filePath = &dirPath | &fileName;
/* start--连接资源 */ Local JavaObject &url1 = CreateJavaObject("java.net.URL", &url); Local JavaObject &connection = GetJavaClass("java.net.HttpURLConnection"); &connection = &url1.openConnection(); rem 配置请求头; For &i = 1 To &headers.ChildCount Local string &key = &headers.GetPropertyNameAt(&i); Local string &value = &headers.GetProperty(&key); &connection.setRequestProperty(&key, &value); End-For; /* end--连接资源 */ /* &connection.setRequestProperty("Host", "localhost"); &connection.setRequestProperty("x-qys-accesstoken", "UEaiJwzIHg"); &connection.setRequestProperty("x-qys-signature", "53d912fd5561eac3ecb54cda88c86628"); &connection.setRequestProperty("x-qys-timestamp", "0"); */ rem &connection.setRequestMethod("GET"); rem &connection.connect(); rem &r = CreateJavaObject("java.io.BufferedReader", CreateJavaObject("java.io.InputStreamReader", &connection.getInputStream())); rem &line = &r.readLine(); /* start--获取文件后缀名 */ Local string &contStr = &connection.getHeaderField("Content-Disposition"); Local number &post = Find(".", &contStr); Local string &extFileName = Substring(&contStr, &post, Len(&contStr) + 1 - &post); &filePath = &filePath | &extFileName; /* end--获取文件后缀名 */ /* Local JavaObject &file = CreateJavaObject("java.io.File", &filePath); Local JavaObject &FileUtils = GetJavaClass("org.apache.commons.io.FileUtils"); &FileUtils.copyInputStreamToFile(&connection.getInputStream(), &file); */ /* start--将文件写入服务器 */ Local JavaObject &fileOutputStream = CreateJavaObject("java.io.FileOutputStream", &filePath); Local JavaObject &buffer = CreateJavaArray("byte[]", 8192); Local number &n = 0; While &n <> - 1 &n = &connection.getInputStream().read(&buffer); If &n <> - 1 Then &fileOutputStream.write(&buffer, 0, &n); End-If; End-While; /* end--将文件写入服务器 */ Return &filePath; End-Function; |
四、效果
调用该方法后会将第三方系统的文件下载到服务器的临时目录,并返回文件绝对路径,后续的文件保存交给开发者。