Drools KIEServer规则then段insert的对象未在响应结果中返回
问题原因
- 标识符重名冲突:调用
commandsFactory.newInsert(location, "LocationApproval")时,将输入的Location对象的输出标识设为了LocationApproval,因此响应中该key对应的是输入的Location对象,和规则生成的结果重名冲突。 - 未指定返回规则插入的事实:KIE Server默认不会自动返回规则执行过程中通过
insert插入到工作内存的新事实,需要手动添加命令获取指定类型的事实。 - 代码冗余(非核心问题):提前创建了
batchCommand对象,但最终调用接口时重新生成了BatchExecution,未使用已定义的对象。
解决方案
方案1:新增getObjects命令获取规则生成的事实
直接添加命令获取工作内存中所有LocationApproval类型的对象即可,修改后的调用代码如下:
Location location = new Location(); location.setCity("A"); KieCommands commandsFactory = KieServices.Factory.get().getCommands(); // 修改插入Location的输出标识,避免重名 Command<?> insertLocation = commandsFactory.newInsert(location, "inputLocation"); Command<?> fireAllRules = commandsFactory.newFireAllRules(); // 新增命令:筛选工作内存中所有LocationApproval类型的事实并返回 Command<?> getApprovals = commandsFactory.newGetObjects(object -> object instanceof LocationApproval, "locationApprovalList"); // 组装批量执行命令 Command<?> batchCommand = commandsFactory.newBatchExecution(Arrays.asList(insertLocation, fireAllRules, getApprovals), "session"); ServiceResponse<ExecutionResults> results = ruleServicesClient.executeCommandsWithResults("containerOD", batchCommand);
执行完成后,从响应结果的execution-results.results中取key为locationApprovalList的value,就是规则插入的LocationApproval对象。
方案2:使用全局变量接收输出
也可以通过全局变量的方式直接接收规则返回结果:
- 首先在DRL规则文件头部声明全局变量:
package drl; import com.Location; import com.LocationApproval; // 新增全局变量声明 global com.LocationApproval locationApproval;
- 修改规则的
then逻辑,给全局变量赋值:
rule "Basic_12" salience 65535 when location: Location(city == "A") then // 直接给全局变量赋值,不需要insert locationApproval = new LocationApproval(true,"20"); end
- 修改调用代码,添加设置、获取全局变量的逻辑:
Location location = new Location(); location.setCity("A"); KieCommands commandsFactory = KieServices.Factory.get().getCommands(); Command<?> insertLocation = commandsFactory.newInsert(location, "inputLocation"); // 设置全局变量,第三个参数设为true表示需要返回该全局变量 Command<?> setGlobal = commandsFactory.newSetGlobal("locationApproval", new LocationApproval(), true); Command<?> fireAllRules = commandsFactory.newFireAllRules(); Command<?> batchCommand = commandsFactory.newBatchExecution(Arrays.asList(setGlobal, insertLocation, fireAllRules), "session"); ServiceResponse<ExecutionResults> results = ruleServicesClient.executeCommandsWithResults("containerOD", batchCommand);
执行完成后直接从响应结果中取key为locationApproval的value即可。
内容的提问来源于stack exchange,提问作者user1428716
相关产品推荐
相关产品推荐

