前些时间在项目上遇到一个需求,通过Odata从S4抽出数据之后,调用打印服务器的地址去打印生成PDF,但是打印服务器每次只能接收一条数据,而S4返回的数据有多条,所以需要在CPI中进行循环操作,依次按照索引将对应的单据内容传递给打印服务器,所以就遇到了两个问题:
1.如何将S4返回的内容拆分;
2.如何每次只将对应的数据发送过去,而不丢失原有完整的数据。
第一个问题,如何拆分:
这个问题比较容易解决,S4端返回的内容格式为XML格式,所以在CPI中使用脚本对XML内容进行解析重构,将一个XML拆分为多个XML,存放在数组中,后续按照所以依次访问即可
Groovy中操作XML的介绍文档链接:https://www.baeldung.com/groovy-xml
返回的数据格式如下:
在mapping完返回数据之后,创建Groovy脚本对其进行拆分
执行完这步后,可以看到数据已经被拆分并依次存放为数组,第一个问题已解决。
第二个问题,如何依次访问数组内容而不丢失原有完整数据:
这里问题主要是每次向打印服务器发送数据时,假如从S4返回的body中有10条数据,则需要循环发送10次,而每次body中只能发送一条,那么就需要覆盖掉body中的内容,所以问题就是下次怎么才能获取到最初完整的数据,来根据下标获取第二次发送的数据。
最开始对CPI中各种控件的使用方法不熟悉,不知道如何实现这种需求,查阅资料后,发现有个Write Variables的控件,该控件是将数据可以写入服务器中的存储空间中,可以在任何时候去读取其中的内容,就解决了上面这个问题。
执行后,可以在监控控制台中看到创建的变量
这里我将上述程序中创建的变量删除了,因为在总结这篇文章时,查阅了官网的资料,看到官方针对同一iflow中共享数据的建议是利用Exchange Property来进行数据共享,所以后来采用了这个方式,实现方式如下:
(PS:2022.3.10日更新,当我再后来总结另一个控件的用法时,我才发现其实我这里并不应该用Property,就是应该使用持久化存储的方式,也就是DataStore或者Write Variables,因为在我的这个使用场景下,可能会处理很大量的数据,关于DataStore的使用方式以及其他几种数据共享方式的区别,在我另一篇帖子中有提到:CPI控件Data Store使用介绍)
1.创建属性
2.创建循环调用控件
3.在任何需要使用到原始数据的地方之前,通过content modifier组件获取属性中的数据
什么时候应该使用Exchange Property,什么时候应该使用Write Variables?首先看一下官方文档中对变量的说明:
这里提到两点
第一点,变量会占用客户的服务器存储空间;
第二点,如果不是必要,同一iflow之间数据共享推荐使用Exchange Property。(数据量少时推荐)
场景一:
Iflow最初接收到的header数据在后面需要用到,但是中间有一个远程调用需要删掉该header数据,这种情况,就可以在最开始接收到header之后,通过Exchange Property创建一个属性,将其获取到的header值作为属性存储起来,这个属性将后续在整个iflow中可用。
场景二:
在获取了有效负载,也就是body中的内容后,在后续需要用到这个有效负载,但是中间有一步操作需要更新body中的值,其实就是我这本程序的需求,这种情况下,就可以通过Exchange Property创建一个属性,来将其存储起来。
场景三:
这种场景下,不要在子分支中更改通用的属性,因为分支是并行的,或者以定义的顺序进行处理的,并且存在以下注意点:
1.在传播分支前设置的properties或者header,在子分支中都可以访问到
2.在子分支中设置的properties或者header,在其他子分支中不可以访问到
3.在合并分支后,子分支中设置的属性可以在主分支中访问到,但是子分支中设置的header不可以在合并后访问到
场景四:
当两个独立的iflow之间需要共享数据时,数据只能通过全局变量或者DataStore来共享数据
在设置全局变量时,有一个全局范围的选项,勾上这个选项代表任何iflow可以访问到该变量,不勾则代表只能当前iflow在下次运行时获取到该变量,由此想到了一个在以后项目上可以实际应用到的场景
以上图为例
所有远程调用的链接都是可以配置成外部参数的,方便迁移到Q环境以及P环境后,进行设置地址,而这些参数是可以设置成动态变量的,如上图中的圈2,目前项目上都是每一本iflow迁移过去后,挨个设置新环境的地址,如CPI的日志地址,S4的wsdl地址,FTP服务器的地址,但如果创建一个单独的iflow,专用做将这些通用的地址信息通过全局变量或者DataStore创建,后面每一本iflow中通过content modifier组件去获取到这些变量值,后续在设置地址时将对应的变量动态拼接在url中,即可免除每次迁移都需要重新配置的工作,节省开发时间。
以上。