Rhapsody调用外部类库的多种方式
声明:转至:Rhapsody调用外部类库的多种方式
随着国内医疗软件行业的发展,医院业务需求日渐复杂,在一些场景下,需要通过集成引擎调用外部程序。这里笔者根据自己的经验,简单分享下Rhapsody调用外部类库的多种方式。
Execute Process
Execute Process是Rhapsody提供的调用外部可执行程序的通信点/过滤器,其中通讯点的ConnectionMode只允许设置为Output,故Execute Process通信点只能用于将消息发送至外部程序中;而Execute Process过滤器则不同,它不但可以像通信点那样将消息发送出去,而且可以将外部程序执行结果返回至Rhapsody路由,以便下游过滤器/路由/通信点可以继续对返回结果进行操作,就像其他过滤器的功能一样,如下图所示:
ExecuteProcess过滤器
ExecuteProcess过滤器配置项
.netframework框架下开发代码示例
一、注意事项
1)ExecuteProcess只能调用集成引擎所在服务器下可独立运行的程序,局域网共享的可执行程序也不行
2)可执行程序包含但不限于*.cmd、*.exe、*.jar等,当然像*.jar需要安装java环境,某些使用.net开发的*.exe必须安装特定的.netframework版本方可运行
3)可执行程序入口Main函数中核心代码建议加上try/catch异常捕获处理,否则异常将会被Rhapsody捕获
二、应用场景
根据上述对Execute Process的描述,我们很容易想到什么情况下该使用ExecuteProcess:
1)Rhapsody需要与外部系统进行交互,并需要对交互结果进行二次加工
2)外部系统提供的是成熟的可执行程序或类库
3)如果是类库而不是可执行程序,需要开发者进行二次封装成可执行程序
采用这种方式比较典型的系统有省市医保接口,各医疗软件公司早年使用C++、Delphi等开发的应用系统或类库等,均可采用该方式与Rhapsody进行交互。
JavaScript
JavaScript过滤器可以说是Rhapsody中最考验编码能力的组件了,虽然我们的产品重配置轻开发,但遇到某些较为复杂的业务需求,需要使用Java原生代码或调用外部Jar架包才能解决时,也是不错的选择。
Javascript调用外部架包有三种方式,每种方式的特点不尽相同。
一、Auxiliary方式
Auxiliary方式指的是将外部Jar包附加到Javascript过滤器中,如下图所示:
Auxiliary方式
其中com.lyniate.rhapsody.his.jar引用了fastjson-1.2.80.jar架包,故需将fastjson一并附加到Javascript过滤器上。
我们简单看一下com.lyniate.rhapsody.his中的代码
患者管理类
package com.lyniate.rhapsody.his;
import com.alibaba.fastjson.JSON;
/**
* 患者管理类
* @author BalanceChang
*
*/
publicfinalclass PatientImpl implements PatientInterface{
private Patient patient = null;
@Override
public String getPatientInfo() {
// TODO Auto-generated method stub
return JSON.toJSONString(patient);
}
@Override
public Patient setPatientInfo(String patientInfo) {
// TODO Auto-generated method stub
patient = JSON.parseObject(patientInfo, Patient.class);
returnpatient;
}
@Override
publicboolean checkSSN() {
returnpatient.getSsn().length() == 18;
}
}
患者管理接口
package com.lyniate.rhapsody.his;
/**
* 患者管理接口
* @author BalanceChang
*
*/
publicinterface PatientInterface {
public String getPatientInfo();
public Patient setPatientInfo(String patientInfo);
publicboolean checkSSN();
}
患者实体类
package com.lyniate.rhapsody.his;
import java.io.Serializable;
/**
* 患者实体类
* @author BalanceChang
*
*/
publicclass Patient implements Serializable{
privatestaticfinallongserialVersionUID = 1L;
privateintid;
privateintage;
private String name;
private String ssn;
public Patient() {}
public Patient(intid, intage, String name, String ssn) {
this.setId(id);
this.setAge(age);
this.setName(name);
this.setSsn(ssn);
}
publicint getId() {
returnid;
}
publicvoid setId(intid) {
this.id = id;
}
publicint getAge() {
returnage;
}
publicvoid setAge(intage) {
this.age = age;
}
public String getName() {
returnname;
}
publicvoid setName(String name) {
this.name = name;
}
public String getSsn() {
returnssn;
}
publicvoid setSsn(String ssn) {
this.ssn = ssn;
}
}
以下是Javascript过滤器中如何使用外部jar包的调用示例:
Javascript过滤器调用外部jar包代码
var next = output.append(input[0]);
// 必须使用类全名
var patientModule = new com.lyniate.rhapsody.his.PatientImpl();
var patient = patientModule.setPatientInfo(next.text);
log.info(patient.getName());
log.info(patientModule.checkSSN());
以下是测试用例及结果:
测试用例及结果
1、注意事项:
1)使用Eclipse导出Jar架包时,选择如下图所示:
2)附加到Javascript过滤器时,所引用的其他jar包不要忘记一并附加上
3)Jar架包所依赖的Java运行环境版本必须小于等于引擎Java版本
2、应用场景:
根据对Auxiliary方式的描述,我们可以理清什么时候使用该方式:
1)外部系统提供的是Jar架包
2)因为自身没有配置文件,且依附于现有Java环境,接口方法建议局限于功能而非业务性质,概括来说就是建议只做小规模的数据加工
3)Auxiliary方式无需重新启动Rhapsody,故属于接口热插拔性质
二、lib方式
lib方式指的是将Jar架包直接放至Rhapsody运行目录<RhapsodyEngine>/data/lib文件夹中,这样所有Javascript过滤器均可直接使用Jar架包中的接口方法
该方式在Javascript过滤器中的调用与Auxiliary方式一样,这里不再赘述。
注意事项:
1)需重新启动 Rhapsody 进行激活
2)与Auxiliary方式相似,所引用的jar包需一并放至lib文件夹中
3)Jar架包所依赖的Java运行环境版本必须小于等于引擎Java版本
三、Share Javascript Library方式
严格来讲ShareJavascript Library(以下简称SJL)方式是前两种的延伸,SJL是Rhapsody开发者自定义的一系列Javascript类库,在Rhapsody IDE->View->Share Javascript Libraries中打开,如下图所示:
Share Javascript Library
以下是Javascript过滤器调用代码示例:
Javascript过滤器调用代码
var next = output.append(input[0]);
//Call require with the Libraries name
var patientLib = require("PatientLib");
//Call the Function by its name on the resulting object, passing in any parameters required
var result = patientLib.checkSSN(next.text);
log.info(result);
1、注意事项:
因为Javascript是脚本语言,后编译运行,故这里的PatientImpl类是否存编码时无需关心,当checkSSN方法被真正调用时才会进行编译校验,如果调用者Javascript过滤器没有附加PatientImpl类所属包或lib下没有找到,则会报错。
2、应用场景:
当某些处理步骤经常重复出现时,可将其提炼为SJL方法,这么做会节省大量重复Javascript代码,且只需在SJL中进行一次修改即可影响全部。
RDK
使用RDK调用外部类库的细节大家可以查看我们公众号有关RDK的系列文章,里面有详细描述,这里着重分析下何时使用RDK调用外部架包更为合理。
笔者认为RDK的设计初衷是为开发者提供研发Rhapsody自定义组件(通信点/过滤器)的通道。既然是自定义组件,开发者应该将经常被使用到,Rhapsody自带组件无法完全满足的功能进行封装,这样在进行工程开发时,只需拖拽RDK组件,进行简单的配置即可完成复杂的业务逻辑处理。
以下对调用外部类库各种方式特点进行了汇总,其中“热插拔”指的是该方式无需引擎重启,只需自身替换即可完成功能更新,如下表所示:
方式 | 热插拔 | 性能 | 需二次开发 |
Execute Process | 是 | 中,取决于外部系统性能 | 若提供的是非可执行程序,则需要二次封装 |
Javascript-Auxiliary | 是 | 低,需先加载附加文件,再进行二次编译 | 否 |
Javascript-lib | 否 | 中,只需进行二次编译 | 否 |
RDK | 否 | 高,引擎启动过程中完成预加载 | 是 |