本文主要介绍Drools6.4.Final版本与SpringMVC的整合。网上现有的教程大多数不能完整运行,本文将会提供具体的操作过程以及相应的注意事项,保证Demo代码是可以跑通的。
开发环境
- macOS High Sierra
- Intellij IDEA 2017.2
- Drools 6.4.0.Final
- SpringMVC 4.3.12.RELEASE
- JDK 1.8.0_144
搭建Maven项目
关于具体如何创建一个Maven的Webapp项目我就不赘述了,其实在IDEA中可以一步一步选择的,下面贴出本项目的pom.xml
文件。
pom.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
| <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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.qinjiangbo</groupId> <artifactId>DroolsSpring</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>Drools SpringMVC</name> <url>http://maven.apache.org</url>
<properties> <spring.version>4.3.12.RELEASE</spring.version> <drools.version>6.4.0.Final</drools.version> <slf4j.version>1.7.25</slf4j.version> <fastjson.version>1.2.39</fastjson.version> </properties>
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.kie</groupId> <artifactId>kie-api</artifactId> <version>${drools.version}</version> </dependency> <dependency> <groupId>org.drools</groupId> <artifactId>drools-core</artifactId> <version>${drools.version}</version> </dependency> <dependency> <groupId>org.drools</groupId> <artifactId>drools-compiler</artifactId> <version>${drools.version}</version> </dependency> <dependency> <groupId>org.kie</groupId> <artifactId>kie-spring</artifactId> <version>${drools.version}</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.0.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.2</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>${fastjson.version}</version> </dependency>
</dependencies>
<build> <finalName>DroolsSpring</finalName> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> </build> </project>
|
接着在web.xml
中配置相关的SpringMVC环境。
web.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <display-name>Archetype Created Web Application</display-name>
<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:springContext.xml</param-value> </context-param>
<servlet> <servlet-name>springServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:springContext.xml</param-value> </init-param> </servlet>
<servlet-mapping> <servlet-name>springServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
|
在介绍springContext.xml
文件之前,有必要贴出一下项目的结构,以便于大家有一个更明确的认知。
好,现在分别介绍springContext.xml
,springDrools.xml
以及springMVC.xml
三个文件。
springContext.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.qinjiangbo"/>
<import resource="springDrools.xml"/> <import resource="springMVC.xml"/>
</beans>
|
springDrools.xml
1 2 3 4 5 6 7 8 9 10 11 12 13
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:kie="http://drools.org/schema/kie-spring" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://drools.org/schema/kie-spring http://drools.org/schema/kie-spring.xsd"> <bean id="kiePostProcessor" class="org.kie.spring.annotations.KModuleAnnotationPostProcessor"/> <kie:kmodule id="kModule"> <kie:kbase name="kBase" packages="rules"> <kie:ksession name="kSession" type="stateful"/> </kie:kbase> </kie:kmodule> </beans>
|
springMVC.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/pages/"/> <property name="suffix" value=".jsp"/> </bean> </beans>
|
Fact模型
在Drools中我们使用的Model被称之为事实(Fact)模型,本例中的事实模型是Message.java
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| package com.qinjiangbo.model;
public class Message {
public static final int DEAD = 0; public static final int ALIVE = 1;
private String message; private int status;
public String getMessage() { return message; }
public void setMessage(String message) { this.message = message; }
public int getStatus() { return status; }
public void setStatus(int status) { this.status = status; }
}
|
rules文件
我们来编写一下相关的规则文件,一般是以.drl
结尾。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| package rules; import com.qinjiangbo.model.*;
rule "rule1" when
m:Message(status == Message.DEAD, printMsg: message); then System.out.println(printMsg); m.setMessage("I'm alive~"); m.setStatus(Message.ALIVE);
update(m); end
rule "rule2" when Message(status == Message.ALIVE, printMsg: message); then System.out.println(printMsg); end
|
Service类和Controller类
在Service类中调用规则引擎相关的逻辑,在Controller中进行Web页面的交互。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| package com.qinjiangbo.service;
import com.alibaba.fastjson.JSON; import com.qinjiangbo.model.Message; import org.kie.api.cdi.KSession; import org.kie.api.runtime.KieSession; import org.springframework.stereotype.Service;
@Service public class MessageService {
@KSession("kSession") private KieSession kieSession;
public String updateMessage() { Message message = new Message(); message.setMessage("Left 4 Dead 2"); message.setStatus(Message.DEAD); kieSession.insert(message); kieSession.fireAllRules(); return JSON.toJSONString(message); }
}
|
注意
上面的@KSession("kSession")
注解在使用的时候要在springDrools.xml
文件中声明kiePostProcessor
为注解类型的org.kie.spring.annotations.KModuleAnnotationPostProcessor
,否则会失效的。另外,这里使用的KieSession
其实就是指代的StatefulKieSession
类,不要使用KieSession
去声明一个StatelessKieSession
类的对象。这里要在springDrools.xml
文件中把<kie:ksession name="kSession" type="stateful"/>
类型声明为stateful
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| package com.qinjiangbo.controller;
import com.qinjiangbo.service.MessageService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView;
@Controller @RequestMapping("/") public class MessageController {
@Autowired private MessageService messageService;
@RequestMapping("/") public String index() { return "index"; }
@RequestMapping("/update") public ModelAndView update() { ModelAndView modelAndView = new ModelAndView("success"); String message = messageService.updateMessage(); modelAndView.addObject("message", message); return modelAndView; } }
|
测试结果
在浏览器中输入http://localhost:8080/update
,就可以看到如下页面:
Bingo,那就证明整合成功啦!