DWF处理文件数据的基本原理
在DWF中涉及到非机构化数据的控件包括:
- PC端:“多文件上传”、“上传文件”、“图片”实现非结构化数据,如:文件、图片、视频、音频的上传和显示。
- 移动端:“上传文件”、“图片”、“拍照”、“录音”实现非结构化数据,如:文件、图片、视频、音频的上传和显示。
当文件被上传到DWF的服务器端以后,会在数据库中记录文件的元信息和路径,同时将文件重命名后存放在指定位置,上述控件通过记录的元信息,构造合法的url对文件进行显示。
在DWF之中,涉及非结构化的文件数据类型有两种:LocalFile和String,对应的有2种文件存储方法:
属性为LocalFile类型的文件存储
文件在服务器存储的位置和原理
第一种是将文件存储在application.properties指定文件仓库路径,然后通过dwf-app.jar对外公开的restful api完成文件上传后改名存储。application.properties文件中的设定文件存储位置的配置变量名字和默认取值为:“data-model.plugin.repository.path=/opt/dwf3.0-deploy/file-repository”。
当DWF中实体类或者关联类上绑定属性为Localfile类型的时候,上传到服务器端的文件命名方式为:/opt/dwf3.0-deploy/file-repository/{类英文名}/{属性名}/{对象的oid},而DWF的对象上含有Localfile类型相应的属性的取值则是从浏览器上传时原始的文件文件名。
文件上传后如何构造对应的URL
一旦文件被上传可通过DWF在自带的restful api: api/v1/omf/classes/${className}/objects/attributes/${attributeName}/bytes?attachemenets=ture拼接url从获得文件,这个url可以作为ai服务的参数输入。
假设:Asset实体类有一个assetImg的LocalFile属性,那么在前端脚本中,拼接URL的模板和需要带入的参数如下:
let className = "Asset"; let attributeName = "assetImg"; let oid = this.obj.oid; let rand = Math.Random(); // 增加的任意随机数是为了防止浏览器的缓存机制导致文件加载被跳过 let secondaryFolder = "app-api"; //二级目录,当使用反向代理实现域名转发的时候使用 let fileUrl = `http://${this.env.serverIp}:${this.env.serverPort}/${secondaryFolder}/dwf/v1/omf/classes/${className}/objects/${oid}/attributes/${attributeName}/bytes?attachements=true&r=${rand}`; window.open(fileUrl);
后端脚本的专用函数
在后端脚本可以利用this.omf.setLocalFile和this.omf.getFilePath获取LocalFile属性对应文件的路径或者设置一个路径到对象的属性上,详情见后端脚本的介绍:
- setLocalFile(String oid, String className, String filePath)
- getFilePath(String oid, String className, String attrName)
属性为String类型的文件存储
文件存储的位置和原理
第二种方法是利用和DWF的Web服务器tomcat,将文件上传到这个Web服务器下面对应的webapp/multi-file/multifile_default目录下实现保存,前端控件每上传一个文件dwf会为该文件生成一个oid并且将文件改名为新生成的oid加上原始文件的后缀放到tomcat服务器webapp/multi-file/multifile_defaul目录下,文件命名模式为:/opt/apache-tomcat/webapps/multi-file/multifile_default/${yyyy-mm-dd}/${oid}.后缀,其中yyyy-mm-dd是上传文件的日期,而oid则是文件名,带后缀。
当实体类上绑定属性为String类型,并且是通过DWF内置的文件管理控件(如:附件、图片、手机端的多文件、拍照、录音等)上传文件的时候将采用这种方式。
String类型相对LocalFile类型的优势
以String为基础的文件存储方式,克服了第一种以LcoalFile为基础实现文件存储的诸多不足,是推荐的文件存储方法,String类型优势有:
- 由于通过Tomcat服务器上传下载文件,将负载从restful api分离出来,避免了上传下载大文件时的对网络的竞争,提升了DWF的并发响应能力。
- 可以利用tomcat服务器自身的压缩功能加速传输速度,不会消耗DWF的restful api服务自身的算力。
- 利用String存储方式,也有利于将来在需要的时候将文件存储与主流对象存储服务合并。
- 解除了LocalFile只能上传1个文件的限制,通过多文件上传控件可以做到在1个属性中存储多个文件元信息。
因此,在未来的应用中,如果涉及非机构化数据,应尽量采用String类型的属性在表单中配合文件控件使用。
文件上传后如何构造对应的URL
因为文件是存在于tomcat服务器的webapp下面,所以上传以后的文件对应的url拼接公式如下,假设上传之后的文件对应的文件对应的oid存储在变量fileOid之中,后缀为png。
let fileUrl = `http://${this.env.serverIp}:${this.env.serverPort}/multi-file/multifile_default/${fileOid}.png` window.open(fileUrl);
String类型记录文件元信息的格式
为了将实质性的上传文件和DWF数据库中对象包含的String类型属性的取值联系起来,以便前端控件能够正确拼接出正确的URL,同时保持向下兼容性。在DWF中约定了一个描述文件元信息和路径对应的格式,分成3类,规范如下:
- 外部URL:当String类型属性的取值为http://或者https://开头,则意味着String属性里只是存储了1个文件,改文件并非由DWF管理,是互联网上面通过url可以访问的外部文件,此时,前端控件将直接打开文件对应的url,并将其显示成图片、音频、视频或者文件下载链接。这种存储可以用于处理如CDN图片、外部对象服务提供的url。
- 相对路径:当String类型属性的取值为/开头,则意味着这个String类型属性记录了一个文件对应的相对路径,在前面拼接上DWF服务器url前缀,即可够造出文件在dwf对应完整的url,在这个相对路径之中要求必须具有名称为originalFileName的url参数,其记录了原始的文件名,例如:
/multi-file/multifile_default/2024-02-16/DC9EF30C5CE8E8471708053931931.png?originalFileName=微信截图_20210124152907.png
- JSON数组:当String类型属性的取值为一个JSON数组的时候,则说明文件是存储在DWF内部tomcat文件夹内,由DWF的多文件上传、拍照等控件生成的文件元信息,此时数组中的每个元素是一个JSON对象,包含下面的属性:
- name:原始的文件名
- size:文件的大小,以KB为单位
- file_id:上传以后的文件oid
- url:相对路径,在前面补充serverUrl即可获得有意义的url。
下面是一个例子:
[{"name":"微信截图_20210124152711.png","size":"1223.69140625KB","file_id":"3394BD3DF5352141A861145F16F20A32","url":"/multi-file/multifile_default/2024-02-16/72FDB1CD2FF326431708054237594.png"} ,{"name":"微信截图_20210124152907.png","size":"1045.9091796875KB","file_id":"9821B0D1529D434EBB0FA7D7BFCD2179","url":"/multi-file/multifile_default/2024-02-16/1DE51837CC38674C1708054238647.png"}]
上述规范中,以JSON数组为基础的规范是推荐的规范。
后端脚本的处理
对于String类型的文件存储,并没有提供专门的后端脚本函数,如果不希望通过url获取文件,可以根据对象的属性得到文件在服务器的存储的路径,然后利用后端脚本的Graalvm引擎将Java转Javascript实现对文件的处理。
前端控件提供的函数
在前面介绍的文件基础上,还可以利用前端控件提供的一些函数和变量帮助简化脚本编写,下面简单介绍一下:
PC端表单控件
- 文件上传(Attachements):针对单个文件上传的控件,除了通过getValue自行判断以外,可以通过fileUrl获得完整的url:
- fileUrl:属性,在前端脚本中,可直接通过getAddinById获得控件句柄以后,利用fileUrl属性即可获得有意义的文件url,省去了拼接url的麻烦
- 多文件上传(MultiFileList):只支持String类型,通过getValue可以获得以相对路径url为基础的JSON数组
- getFileList(withUrl = false):获得具有完整url而非相对url的文件列表JSON数组
- 图片(Images):图片可能来自于String类型属性,LocalFile类型属性,DWF全局图片库或者互联网上有意义的url对应的图片
- ImageUrl:通过getAddinById获得控件的引用以后,直接获得有意义的文件对应完整url
移动端表单控件
- 照相(Camera):由于可以通过拍摄多次,所以绑定String类型属性,其中有意义的属性是:
- fileList:通过getAddinById获得控件引用之后,利用fileList可直接获取具有完整url的数组,数组中元素的内容和String类型元信息格式一致,唯一不同的地方在于url是完整的url
- 录音(Record):
- fileList:通过getAddinById获得控件引用之后,利用fileList可直接获取具有完整url的数组,数组中元素的内容和String类型元信息格式一致,唯一不同的地方在于url是完整的url
- 图片(Images):图片可能来自于String类型属性,LocalFile类型属性,DWF全局图片库或者互联网上有意义的url对应的图片
- ImageUrl:通过getAddinById获得控件的引用以后,直接获得有意义的文件对应完整url
- 上传文件(Attachments):和PC端不同,移动端上传文件同时囊括了单文件和多文件上传的能力
- fileList:通过getAddinById获得控件引用之后,利用fileList可直接获取具有完整url的数组,数组中元素的内容和String类型元信息格式一致,唯一不同的地方在于url是完整的url
其他渠道上传文件的存储位置
最后,与DWF有关的资源文件上传的目录包括下面几个,当使用后端脚本在服务器端处理的时候需要了解这些文件都存储在哪里,以何种方式命名:
- 图片管理器中的图片存放目录:/opt/dwf3.0-deploy/file-repository/picture_management/
文件上传后由图片管理器自动生成oid加上原始图片后缀,url拼接方式是利用files-download接口实现下载:http://${this.env.serverIp}:${this.env.serverPort}/${secondaryFolder}/dwf/v1/files-download/${oid}
- 上传到资源库中文件存放的目录:/opt/apache-tomcat/webapps/resources
资源文件上传后由DWF的资源管理工具自动生成,通过该工具可以看到产生的相对路径。
- html扩展(超级控件)生成文件存放目录 :/opt/apache-tomcat/webapps/code
- 大屏中上传的文件存放目录:/opt/apache-tomcat/webapps/bv-file