9.3 保险产品准入规则

全套代码及资料全部完整提供,点此处下载

9.3.1 决策表

前面我们编写的规则文件都是drl形式的文件,Drools除了支持drl形式的文件外还支持xls格式的文件(即Excel文件)。这种xls格式的文件通常称为决策表(decision table)。

决策表(decision table)是一个“精确而紧凑的”表示条件逻辑的方式,非常适合商业级别的规则。决策表与现有的drl文件可以无缝替换。Drools提供了相应的API可以将xls文件编译为drl格式的字符串。

一个决策表的例子如下:

决策表语法:

关键字 说明 是否必须
RuleSet 相当于drl文件中的package 必须,只能有一个。如果没有设置RuleSet对应的值则使用默认值rule_table
Sequential 取值为Boolean类型。true表示规则按照表格自上到下的顺序执行,false表示乱序 可选
Import 相当于drl文件中的import,如果引入多个类则类之间用逗号分隔 可选
Variables 相当于drl文件中的global,用于定义全局变量,如果有多个全局变量则中间用逗号分隔 可选
RuleTable 它指示了后面将会有一批rule,RuleTable的名称将会作为以后生成rule的前缀 必须
CONDITION 规则条件关键字,相当于drl文件中的when。下面两行则表示 LHS 部分,第三行则为注释行,不计为规则部分,从第四行开始,每一行表示一条规则 每个规则表至少有一个
ACTION 规则结果关键字,相当于drl文件中的then 每个规则表至少有一个
NO-LOOP 相当于drl文件中的no-loop 可选
AGENDA-GROUP 相当于drl文件中的agenda-group 可选

在决策表中还经常使用到占位符,语法为$后面加数字,用于替换每条规则中设置的具体值。

上面的决策表例子转换为drl格式的规则文件内容如下:

package rules;

import com.itheima.drools.entity.PersonInfoEntity;
import java.util.List;
global java.util.List listRules; rule "personCheck_10"
salience 65535
agenda-group "sign"
when
$person : PersonInfoEntity(sex != "男")
then
listRules.add("性别不对");
end rule "personCheck_11"
salience 65534
agenda-group "sign"
when
$person : PersonInfoEntity(age < 22 || age > 25)
then
listRules.add("年龄不合适");
end rule "personCheck_12"
salience 65533
agenda-group "sign"
when
$person : PersonInfoEntity(salary < 10000)
then
listRules.add("工资太低了");
end

要进行决策表相关操作,需要导入如下maven坐标:

<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-decisiontables</artifactId>
<version>7.10.0.Final</version>
</dependency>

通过下图可以发现,由于maven的依赖传递特性在导入drools-decisiontables坐标后,drools-core和drools-compiler等坐标也被传递了过来

Drools提供的将xls文件编译为drl格式字符串的API如下:

String realPath = "C:\\testRule.xls";//指定决策表xls文件的磁盘路径
File file = new File(realPath);
InputStream is = new FileInputStream(file);
SpreadsheetCompiler compiler = new SpreadsheetCompiler();
String drl = compiler.compile(is, InputType.XLS);

Drools还提供了基于drl格式字符串创建KieSession的API:

KieHelper kieHelper = new KieHelper();
kieHelper.addContent(drl, ResourceType.DRL);
KieSession session = kieHelper.build().newKieSession();

基于决策表的入门案例:

第一步:创建maven工程drools_decisiontable_demo并配置pom.xml文件

<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-decisiontables</artifactId>
<version>7.10.0.Final</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>

第二步:创建实体类PersonInfoEntity

package com.itheima.drools.entity;

public class PersonInfoEntity {
private String sex;
private int age;
private double salary; public String getSex() {
return sex;
} public void setSex(String sex) {
this.sex = sex;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public double getSalary() {
return salary;
} public void setSalary(double salary) {
this.salary = salary;
}
}

第三步:创建xls规则文件(可以直接使用资料中提供的testRule.xls文件)

第四步:创建单元测试

@Test
public void test1() throws Exception{
String realPath = "d:\\testRule.xls";//指定决策表xls文件的磁盘路径
File file = new File(realPath);
InputStream is = new FileInputStream(file);
SpreadsheetCompiler compiler = new SpreadsheetCompiler();
String drl = compiler.compile(is, InputType.XLS); System.out.println(drl);
KieHelper kieHelper = new KieHelper();
kieHelper.addContent(drl, ResourceType.DRL);
KieSession session = kieHelper.build().newKieSession(); PersonInfoEntity personInfoEntity = new PersonInfoEntity();
personInfoEntity.setSex("男");
personInfoEntity.setAge(35);
personInfoEntity.setSalary(1000); List<String> list = new ArrayList<String>();
session.setGlobal("listRules",list); session.insert(personInfoEntity); session.getAgenda().getAgendaGroup("sign").setFocus(); session.fireAllRules(); for (String s : list) {
System.out.println(s);
}
session.dispose();
}

9.3.2 规则介绍

各保险公司针对人身、财产推出了不同的保险产品,作为商业保险公司,筛选出符合公司利益最大化的客户是非常重要的,即各保险产品的准入人群是不同的,也就是说保险公司会针对不同的人群特征,制定不同的产品缴费和赔付规则。

我们来看一下某保险产品准入规则的简化版,当不满足以下规则时,系统模块需要返回准入失败标识和失败原因

规则1:  保险公司是:PICC
规则2: 销售区域是:北京、天津
规则3: 投保人年龄:0 ~ 17岁
规则4: 保险期间是:20年、25年、30年
规则5: 缴费方式是:趸交(一次性交清)或年交
规则6: 保险期与交费期规则一:保险期间为20年期交费期间最长10年交且不能选择[趸交]
规则7: 保险期与交费期规则二:保险期间为25年期交费期间最长15年交且不能选择[趸交]
规则8: 保险期与交费期规则三:保险期间为30年期交费期间最长20年交且不能选择[趸交]
规则9: 被保人要求:(投保年龄+保险期间)不得大于40周岁
规则10: 保险金额规则:投保时约定,最低为5万元,超过部分必须为1000元的整数倍
规则11: 出单基本保额限额规则:线上出单基本保额限额62.5万元,超62.5万元需配合契调转线下出单

在本案例中规则文件是一个Excel文件,业务人员可以直接更改这个文件中指标的值,系统不需要做任何变更。

9.3.3 实现步骤

本案例还是基于Spring Boot整合Drools的架构来实现。

第一步:创建maven工程insuranceInfoCheck并配置pom.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starters</artifactId>
<version>2.0.6.RELEASE</version>
</parent>
<groupId>com.itheima</groupId>
<artifactId>insuranceInfoCheck</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<!--drools规则引擎-->
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>7.6.0.Final</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>7.6.0.Final</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-templates</artifactId>
<version>7.6.0.Final</version>
</dependency>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-api</artifactId>
<version>7.6.0.Final</version>
</dependency>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-spring</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
</exclusions>
<version>7.6.0.Final</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

第二步:创建/resources/application.yml文件

server:
port: 8080
spring:
application:
name: insuranceInfoCheck

第三步:创建实体类InsuranceInfo

package com.itheima.drools.entity;

/**
* 保险信息
*/
public class InsuranceInfo {
private String param1;//保险公司
private String param2;//方案代码
private String param3;//渠道号
private String param4;//销售区域
private String param5;//投保年龄
private String param6;//保险期间
private String param7;//缴费期间
private String param8;//缴费方式
private String param9;//保障类型
private String param10;//等待期
private String param11;//犹豫期
private String param12;//职业类型
private String param13;//保额限制
private String param14;//免赔额
private String param15;//主险保额
private String param16;//主险保费
private String param17;//附加险保额
private String param18;//附加险保费
private String param19;//与投保人关系
private String param20;//与被保人关系
private String param21;//性别
private String param22;//证件
private String param23;//保费
private String param24;//保额 //getter setter省略
}

第四步:创建决策表文件(也可以直接使用实战资料中提供的insuranceInfoCheck.xls文件)

第五步:封装工具类KieSessionUtils

package com.itheima.drools.utils;

import com.itheima.drools.entity.InsuranceInfo;
import com.itheima.drools.entity.PersonInfoEntity;
import org.drools.decisiontable.InputType;
import org.drools.decisiontable.SpreadsheetCompiler;
import org.kie.api.builder.Message;
import org.kie.api.builder.Results;
import org.kie.api.io.ResourceType;
import org.kie.api.runtime.KieSession;
import org.kie.internal.utils.KieHelper;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List; public class KieSessionUtils {
private KieSessionUtils() { }
// 把xls文件解析为String
public static String getDRL (String realPath) throws FileNotFoundException {
File file = new File(realPath); // 例如:C:\\abc.xls
InputStream is = new FileInputStream(file);
SpreadsheetCompiler compiler = new SpreadsheetCompiler();
String drl = compiler.compile(is, InputType.XLS);
System.out.println(drl);
return drl;
} // drl为含有内容的字符串
public static KieSession createKieSessionFromDRL(String drl) throws Exception{
KieHelper kieHelper = new KieHelper();
kieHelper.addContent(drl, ResourceType.DRL);
Results results = kieHelper.verify();
if (results.hasMessages(Message.Level.WARNING, Message.Level.ERROR)) {
List<Message> messages = results.getMessages(Message.Level.WARNING, Message.Level.ERROR);
for (Message message : messages) {
System.out.println("Error: "+message.getText());
}
// throw new IllegalStateException("Compilation errors were found. Check the logs.");
}
return kieHelper.build().newKieSession();
} // realPath为Excel文件绝对路径
public static KieSession getKieSessionFromXLS(String realPath) throws Exception {
return createKieSessionFromDRL(getDRL(realPath));
}
}

第六步:创建RuleService类

package com.itheima.drools.service;

import com.itheima.drools.entity.InsuranceInfo;
import com.itheima.drools.utils.KieSessionUtils;
import org.kie.api.runtime.KieSession;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List; @Service
public class RuleService {
public List<String> insuranceInfoCheck(InsuranceInfo insuranceInfo) throws Exception{
KieSession session = KieSessionUtils.getKieSessionFromXLS("D:\\rules.xls");
session.getAgenda().getAgendaGroup("sign").setFocus(); session.insert(insuranceInfo); List<String> listRules = new ArrayList<>();
session.setGlobal("listRules", listRules); session.fireAllRules(); return listRules;
}
}

第七步:创建RuleController类

package com.itheima.drools.controller;

import com.itheima.drools.entity.InsuranceInfo;
import com.itheima.drools.service.RuleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.List;
import java.util.Map; @RestController
@RequestMapping("/rule")
public class RuleController {
@Autowired
private RuleService ruleService; @RequestMapping("/insuranceInfoCheck")
public Map insuranceInfoCheck(){
Map map = new HashMap(); //模拟数据,实际应为页面传递过来
InsuranceInfo insuranceInfo = new InsuranceInfo();
insuranceInfo.setParam1("picc");
insuranceInfo.setParam4("上海");
insuranceInfo.setParam5("101");
insuranceInfo.setParam6("12");
insuranceInfo.setParam7("222");
insuranceInfo.setParam8("1");
insuranceInfo.setParam13("3"); try {
List<String> list = ruleService.insuranceInfoCheck(insuranceInfo);
if(list != null && list.size() > 0){
map.put("checkResult",false);
map.put("msg","准入失败");
map.put("detail",list);
}else{
map.put("checkResult",true);
map.put("msg","准入成功");
}
return map;
} catch (Exception e) {
e.printStackTrace();
map.put("checkResult",false);
map.put("msg","未知错误");
return map;
}
}
}

第八步:创建启动类DroolsApplication

package com.itheima.drools;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication
public class DroolsApplication {
public static void main(String[] args) {
SpringApplication.run(DroolsApplication.class);
}
}

全套代码及资料全部完整提供,点此处下载

第2-4-10章 规则引擎Drools实战(3)-保险产品准入规则的更多相关文章

  1. JAVA规则引擎 -- Drools

    Drools是一个基于java的规则引擎,开源的,可以将复杂多变的规则从硬编码中解放出来,以规则脚本的形式存放在文件中,使得规则的变更不需要修正代码重启机器就可以立即在线上环境生效. 本文所使用的de ...

  2. [Drools]JAVA规则引擎 -- Drools

    Drools是一个基于Java的规则引擎,开源的,可以将复杂多变的规则从硬编码中解放出来,以规则脚本的形式存放在文件中,使得规则的变更不需要修正代码重启机器就可以立即在线上环境生效. 本文所使用的de ...

  3. drools规则引擎与kie-wb和kie-server远程执行规则(7.18.0.Final)

    最近研究了一下规则引擎drools. 这篇博客带你搭建并运行一个可在线编辑,在线打包,远程执行的规则引擎(drools) 本篇博客同时参考https://blog.csdn.net/chinrui/a ...

  4. 【java规则引擎】《Drools7.0.0.Final规则引擎教程》第3章 3.2 KIE概念&FACT对象

    转载:https://blog.csdn.net/wo541075754/article/details/74943236 3.2.1 什么是KIE KIE(Knowledge Is Everythi ...

  5. 开源规则引擎 drools

    java语言开发的开源业务规则引擎 DROOLS(JBOSS RULES )具有一个易于访问企业策略.易于调整以及易于管理的开源业务规则引擎,符合业内标准,速度快.效率高.业务分析师或审核人员可以利用 ...

  6. 规则引擎drools封装

    一.前言 网上规则引擎drools介绍很多,并且有很多细致的说明,作者也不敢托大说自己的好用,但作者经过2个项目使用过规则引擎后,自己对规则引擎的理解并进行封装,对规则内容及如何使用,有自己的一番实践 ...

  7. 开源规则引擎 Drools 学习笔记 之 -- 1 cannot be cast to org.drools.compiler.kie.builder.impl.InternalKieModule

    直接进入正题 我们在使用开源规则引擎 Drools 的时候, 启动的时候可能会抛出如下异常: Caused by: java.lang.ClassCastException: cn.com.cheng ...

  8. [Drools]JAVA规则引擎 -- Drools 2

    上一篇文章 http://blog.csdn.net/quzishen/archive/2011/01/25/6163012.aspx 描述了一些常用的drools的语法标签和一个模拟实例即发送积分的 ...

  9. 使用规则引擎Drools计算圆周率PI

    实际上是使用规则引擎能够更新工作内存区重新匹配规则实现迭代功能. 使用了策略模式实现. <规则引擎与RETE算法介绍> PPT : http://files.cnblogs.com/lov ...

  10. 【java规则引擎】《Drools7.0.0.Final规则引擎教程》第4章 4.2 activation-group& dialect& date-effective

    转载至:https://blog.csdn.net/wo541075754/article/details/75511887 activation-group 该属性将若干个规则划分成一个组,统一命名 ...

随机推荐

  1. PLG SaaS 产品 Figma 商业模式拆解

    9 月 15 日,Figma 的 CEO Dylan Field 发布消息:今天,Figma 宣布接受 Adobe 的收购... Adobe 以约 200 亿美元收购 Figma,这也是 Adobe ...

  2. ProxySQL Cluster 高可用集群 + MySQL MGR环境部署 (多写模式) 部署记录

    文章转载自:https://blog.51cto.com/u_6215974/4937192 ProxySQL 在早期版本若需要做高可用,需要搭建两个实例,进行冗余.但两个ProxySQL实例之间的数 ...

  3. centos7使用yum方式安装redis6

    yum -y install epel-release wget make gcc-c++ cd /opt wget https://download.redis.io/releases/redis- ...

  4. 查看pod对应的DNS域名

    单个pod # kubectl exec redis-pod-0 -n cluster-redis -- hostname -f redis-pod-0.redis-cluster-service.c ...

  5. Qemu/Limbo/KVM镜像 最精简Linux+Wine,可运行Windows软件,内存占用不到70M,存储占用500M

    镜像特征: Alpine Edge系统 内置Wine 7.8,可运行大量Windows 软件 高度精简,内存占用仅68MB,存储占用仅500MB 完全开源 镜像说明: 用户名为root,密码为空格. ...

  6. 整理一些Windows桌面运维常用的命令,并且整合成脚本

    github地址:alittlemc/toy: 编写些脚本将运维经常所用到小玩意所集成在一起 (github.com) 持续更新! 前言 做过桌面运维的大佬们应该可以很明显感受到这份工作所需要的技能不 ...

  7. sg函数入门理解

    首先理解sg函数必须先理解mex函数 mex是求除它集合内的最小大于等于0的整数,例:mex{1,2}=0:mex{2}=0:mex{0,1,2}=3:mex{0,5}=1. 而sg函数是啥呢? 对于 ...

  8. Flink的异步算子的原理及使用

    1.简介 Flink的特点是高吞吐低延迟.但是Flink中的某环节的数据处理逻辑需要和外部系统交互,调用耗时不可控会显著降低集群性能.这时候就可能需要使用异步算子让耗时操作不需要等待结果返回就可以继续 ...

  9. Linux实战笔记_CentOS7_无法识别NTFS格式的U盘

    注:因为CentOS 默认不识别NTFS的磁盘格式,所以我们要借助另外一个软件ntfs-3g来挂载.自带的yum源没有这个软件,要用第三方的软件源,比如阿里的epel. #安装ntfs-3g cd / ...

  10. IDEA中如何导入jar包、IDEA中找不到对应类改怎样解决?(详细图解过程)

    今天突然心血来潮.用IDEA运行之前用eclipse编写的项目.发现遇到了一些bug,现在习惯了使用maven管理项目的依赖.一时间忘记了怎样将jar包导入项目中.特此记录一下 文章目录 1.未加入j ...