在项目上遇到需要配置计算的需求,学习了下 jexl 表达式引擎 在此记录下
首先导包
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-jexl</artifactId> <version>2.1.1</version> </dependency>
推荐公式在配置时就使用字符拼接好
字符拼接方法:
String Suanfa = null;
String Tiaojian = null;
String Mubiaoziduan = null;
//存储目标字段
String s1 = "";
//存储条件
String s2 = "";
//存储算法
String s3 = "";
//匹配多位大小写英文单词包含下划线
String regExp1 = "([A-Za-z-_]+|[']{1}([A-Za-z-_\\s\\u00C0-\\u00FF]+|[\\u4e00-\\u9fa5]+)[']{1})";
//匹配下划线后一位小写字母
String regExp2 = "(_)([a-z]{1})";
//匹配+,-,*,/
String regExp3 = "[+|-|*|/]";
for (KjfzZtZhuanhuanAlgorithm billAlgorithm : algorithms) {
StringBuffer str = new StringBuffer("if(");
Pattern pattern = null;
Matcher matcher = null;
StringBuffer sb = null;
//目标字段
s1 = StringUtils.isBlank(billAlgorithm.getTargetZiduan()) ? "1 == 1" : billAlgorithm.getTargetZiduan();
//条件
s2 = StringUtils.isBlank(billAlgorithm.getConditionYw()) ? "1 == 1" : billAlgorithm.getConditionYw();
//算法
s3 = StringUtils.isBlank(billAlgorithm.getAlgorithmYw()) ? "1 == 1" : billAlgorithm.getAlgorithmYw();
pattern = Pattern.compile(regExp2);
matcher = pattern.matcher(s1);
sb = new StringBuffer();
while (matcher.find()) {
// 把_小写 格式 改成大写,即驼峰命名,匹配后进行把下划线替换成空,然后转换成大写的
matcher.appendReplacement(sb, matcher.group().replaceAll("_", "").toUpperCase());
}
matcher.appendTail(sb);
if ("1 == 1".equals(sb.toString())) {
Mubiaoziduan = "";
} else {
//计算保存字段
Mubiaoziduan = StrUtil.upperFirstAndAddPre(sb.toString(), "json.set").trim();
// name4 = StrUtil.upperFirstAndAddPre(sb.toString() + "()", "obj.get").trim();
}
sb = new StringBuffer();
pattern = Pattern.compile(regExp1);
matcher = pattern.matcher(s2);
while (matcher.find()) {
if (matcher.group().equals("contains")) {
continue;
}
if (matcher.group().equals("null") || matcher.group().equals("Null") || matcher.group().equals(null)) {
continue;
}
if (matcher.group().contains("'")) {
continue;
}
if (matcher.group().contains("-")) {
continue;
}
if (!matcher.group().equals("")) {
Pattern pattern2 = Pattern.compile(regExp2);
Matcher matcher2 = pattern2.matcher(matcher.group());
StringBuffer sb2 = new StringBuffer();
while (matcher2.find()) {
matcher2.appendReplacement(sb2, matcher2.group().replaceAll("_", "").toUpperCase());
}
matcher2.appendTail(sb2);
String a = StrUtil.upperFirstAndAddPre(sb2.toString() + "()", "obj.get");
matcher.appendReplacement(sb, a);
}
}
matcher.appendTail(sb);
//条件
Tiaojian = sb.toString();
sb = new StringBuffer();
pattern = Pattern.compile(regExp1);
matcher = pattern.matcher(s3);
while (matcher.find()) {
if (!matcher.group().equals("")) {
if (matcher.group().contains("'")) {
continue;
}
Pattern pattern2 = Pattern.compile(regExp2);
Matcher matcher2 = pattern2.matcher(matcher.group());
StringBuffer sb2 = new StringBuffer();
while (matcher2.find()) {
matcher2.appendReplacement(sb2, matcher2.group().replaceAll("_", "").toUpperCase());
}
matcher2.appendTail(sb2);
String a = "";
//自定义值
if (billAlgorithm.getValueMethod() != null && billAlgorithm.getValueMethod().equals(1)){
a = StrUtil.upperFirstAndAddPre(sb2.toString() + "()", "algorit.get");
}else if (sb2.toString().equals("-")) {//原始值
a = "-";
} else {
a = StrUtil.upperFirstAndAddPre(sb2.toString() + "()", "obj.get");
}
matcher.appendReplacement(sb, a);
}
}
matcher.appendTail(sb);
if ("1 == 1".equals(sb.toString())) {
Suanfa = "";
} else {
Suanfa = sb.toString().trim();
}
str.append(Tiaojian);
str.append("){");
if (StringUtils.isBlank(Suanfa)) {
str.append("a = 1;}");
} else {
str.append(Mubiaoziduan);
str.append("(");
str.append(Suanfa);
str.append(");}");
}
billAlgorithm.setZhixingValus(str.toString());
}
billAlgorithm.getTargetZiduan() 为你要set的属性
billAlgorithm.getConditionYw() 为条件 满足改条件再执行set
billAlgorithm.getAlgorithmYw() 为原始值 即要set到 billAlgorithm.getTargetZiduan()属性字段里面的值
以下为例
billAlgorithm.getTargetZiduan() 中的值为 c属性
billAlgorithm.getConditionYw() 为空 如果不为空 即参考注释的str 即 billAlgorithm.getConditionYw()中的值为 a !='1'
billAlgorithm.getAlgorithmYw()中的值为 a+b
PingzhengValueVo vo = new PingzhengValueVo();
KjfzZtPingzhengDatareport pingzhengDatareport = new KjfzZtPingzhengDatareport();
String str = "if(1 == 1){json.setC(obj.getA()+obj.getB());}";
//String str = "if(obj.getA()!='1'){json.setC(obj.getA()+obj.getB());}";
// 创建表达式引擎对象
JexlEngine jexlEngine = new JexlEngine();
// 创建Context对象
JexlContext context = new MapContext();
context.set("obj", pingzhengDatareport);
context.set("json", vo);
Expression expression = null;
// 使用表达式引擎创建表达式对象
log.info("++++++++表达式值为:"+str);
expression = jexlEngine.createExpression(str);
// 使用表达式对象计算
expression.evaluate(context);
如果假设 KjfzZtPingzhengDatareport的属性a=1,b=2
则 PingzhengValueVo 的属性c = 3