如何在Drools DRT模板中传递并读取Map值及问题排查
在Drools DRT模板中传递并使用Map的正确方式
你的代码存在两个核心问题,导致规则无法触发、函数未被调用:
1. Map匹配逻辑完全错误
生成的DRL中namedmap:Map(map:"{key1=value1, key2=value2}")是无效写法:
- Drools没有
map这个内置属性约束,Map类本身也没有名为map的成员变量; - 你把Map的
toString()输出结果当成字符串值来匹配,这不可能匹配到工作内存中的Map对象,导致第一个模式永远匹配失败,整个规则的when条件不成立。
2. 函数参数未正确绑定
规则中compareNamedTags(namedmap,namedTags)的namedTags变量未在when块中定义,Drools无法识别该变量,进一步导致规则逻辑失效。
修正方案
步骤1:编写正确的DRT模板
模板需要将传入的Map转换为Drools可识别的常量语法,同时修正模式匹配和函数调用逻辑:
template "another map" rule "test map_2_@{row.rowNumber}" no-loop true dialect "java" when // 匹配工作内存中的Map事实 namedmap:Map() review:FactNew() // 使用eval调用函数,传入工作内存的Map和模板生成的Map常量 eval(compareNamedTags(namedmap, ${namedTags})) then System.out.println("Value is present in the list: " + namedmap.get("key2")); modify(review){setComment("accepted")} end end template
步骤2:将传入模板的Map转换为DRL常量语法
DRL中表示Map常量的正确写法是new java.util.HashMap(){{ put("key1", "value1"); put("key2", "value2"); }},而非Map的toString()结果。如果用Java代码驱动模板,转换逻辑示例:
public String convertMapToDrlConstant(Map<String, String> map) { StringBuilder sb = new StringBuilder("new java.util.HashMap(){{"); for (Map.Entry<String, String> entry : map.entrySet()) { sb.append(String.format("put(\"%s\", \"%s\");", entry.getKey(), entry.getValue())); } sb.append("}}"); return sb.toString(); }
将该方法生成的字符串作为namedTags参数传入DRT模板,生成的DRL才会有合法的Map常量。
步骤3:确保规则触发的前置条件
- 工作内存中必须插入待匹配的
Map实例和FactNew实例; - 函数
compareNamedTags需放在DRL文件的全局位置(或通过import引入),确保规则能调用到。
验证修正后的DRL示例
生成的合法DRL应该类似:
rule "test map_2_1" no-loop true dialect "java" when namedmap:Map() review:FactNew() eval(compareNamedTags(namedmap, new java.util.HashMap(){{put("key1","value1");put("key2","value2");}})) then System.out.println("Value is present in the list: " + namedmap.get("key2")); modify(review){setComment("accepted")} end
内容的提问来源于stack exchange,提问作者Harsha
相关产品推荐
相关产品推荐

