瘋狂Activiti6.0連載(15)DMN規則匹配表達式

  本文節選自《瘋狂工作流講義(第2版)》

京東購買地址:https://item.jd.com/12246565.html

工作流Activiti6電子書http://blog.csdn.net/boxiong86/article/details/78488562

工作流Activiti6教學視頻http://blog.csdn.net/boxiong86/article/details/78608585

DMN規則匹配表達式

規則引擎中的輸入參數與輸出結果,可以在inputExpression元素下使用MVEL表達式,這樣就意味着在規則匹配以及結果處理上,都使得規則引擎變得很靈活,本小節將以MVEL爲基礎,講述Activiti規則引擎在匹配上的原理。

MVEL表達式簡介

MVEL一款基於Java程序的表達式語言,它支持大部分的Java語法,當前版本爲2.0使用MVEL,可以在XML文檔實現獲取屬性值、進行運算、設置結果等功能,除此之外,還可以對其進行擴展,實現更爲複雜的需求。目前很多開源項目都使用了MVEL表達式,例如DroolsApache Camel等框架。Activiti規則引擎中也使用了MVEL,因此允許在DMN文件使用跟以下代碼片斷類似的表達式:

person.name == Angus && person.age == 30

以上表達式判斷person對象的name屬性值是否爲“Angus”以及age屬性值是否爲30表達式的執行結果爲true或者false本小節將先講述MVEL簡單使用。

執行第一個表達式

下面編寫一個最簡單的表式,使用MVELAPI進行編譯與執行,見代碼清單15-13

代碼清單15-13codes\15\15.5\mvel-test\src\org\crazyit\activiti\FirstTest.java

//進行編譯

Serializable compiledExpression = MVEL

.compileExpression("personName == 'Angus'");

//設置執行參數

Map<String, String> params = new HashMap<String, String>();

params.put("personName", "Angus");

//執行表達式並返回結果

Boolean result = MVEL.executeExpression(compiledExpression, params,

Boolean.class);

//控制檯輸出結果

System.out.println("表達式第一次執行結果:" + result);

//傳入其他 參數,結果將爲false

params.put("personName", "Paris");

//再次執行表達式

result = MVEL.executeExpression(compiledExpression, params,

Boolean.class);

//輸出結果

System.out.println("表達式第二次執行結果:" + result);

代碼清單15-13粗體字代碼,使用了MVELAPI進行表達式編譯和執行。先編譯了“personName == Angus”的表達式,表示personName這個運行參數的值是否爲“Angus”,在運行時,傳入參數Map即可。代碼清單15-13執行了兩次表達式,第一次執行結果爲true,第二次傳入了不等的參數,因此執行結果爲false。運行代碼清單15-13,輸出結果如下:

表達式第一次執行結果:true

表達式第二次執行結果:false

使用對象執行表達式

MVEL表達式中,也支持傳入對象,並可以獲取對象的值或者方法返回值來進行運算,代碼清單15-14中的表達式,使用了Java對象。

代碼清單15-14codes\15\15.5\mvel-test\src\org\crazyit\activiti\ObjectTest.java

//進行編譯

Serializable compiledExpression = MVEL

.compileExpression("person.name == 'Angus' && person.age == 30");

//設置執行參數

Map<String, Object> params = new HashMap<String, Object>();

//設置名稱與年齡均符合條件

Person p = new Person();

p.setName("Angus");

p.setAge(30);

params.put("person", p);

//執行表達式並返回結果,輸出爲true

Boolean result = MVEL.executeExpression(compiledExpression, params,

Boolean.class);

System.out.println("第一次執行表達式結棍:" + result);

//修改參數年齡

Person p2 = new Person();

p2.setName("Angus");

p2.setAge(20);

params.put("person", p2);

//重新執行表達式,結果false

result = MVEL.executeExpression(compiledExpression, params,

Boolean.class);

System.out.println("第二次執行表達式結果:" + result);

代碼清單15-14中,執行的表達式爲,person實例的name屬性值是否爲“Angus”,並且personage屬性值爲30,這兩個條件都符合時,表達式返回true。代碼清單15-14中的粗體字代碼,分別執行了兩次表達,第一次的參數完全符合條件,第二次執行的參數age不符合條件,最終輸出false。執行代碼清單15-14,輸出結果如下:

第一次執行表達式結棍:true

第二次執行表達式結果:false

規則引擎規則匹配邏輯

DMN文件中定義規則入參數和輸出結果的時候,可以在text元素下面寫入MVEL表達式,以下代碼片斷爲rule元素定義:

<rule>

<inputEntry id="inputEntry1">

<text>

<![CDATA[

執行匹配的MVEL達式

]]>

</text>

</inputEntry>

<outputEntry id="outputEntry1">

<text>

<![CDATA[ 

處理輸出結果的MVEL表達式

]]>

</text>

</outputEntry>

</rule>

以上代碼片斷的粗體字代碼,在inputEntry下的text元素,可以使用MVEL表達式,但要注意的是,該表達式的結果必須爲Boolean類型,因爲該表達式決定規則是否匹配。在outputEntry下的text元素,同樣可添加MVEL表達式,該表達式的計算結果就是規則的返回結果,注意要與決策表的輸出結果類型相匹配,請見以下代碼片斷:

<output id="outputId" label="Output 1" name="myResult"typeRef="number" />

<rule>

<inputEntry id="inputEntry1">

<text>

<![CDATA[

執行匹配的MVEL表達式

]]>

</text>

</inputEntry>

<outputEntry id="outputEntry1">

<text>

<![CDATA[ 

輸出結果的MVEL表達式,要返回數字

]]>

</text>

</outputEntry>

</rule>

以上代碼片斷的粗體字代碼,定義了輸出結果的類型爲“number”,如果匹配到的規則,輸出結果的MVEL表達返回的是字符串,則會報出異常。

Activiti規則引擎在讀取inputEntry配置的MVEL表達式時,會進處理,將輸入參數的名稱添加到配置的MVEL表達式前面,組合成新的表達式讓MVEL去執行,在組合成新的表達式時,會有兩種處理方式,請見代碼清單15-15

代碼清單15-15codes\15\15.5\dmn-mvel\resource\dmn\GetExpression.dmn

<rule>

<inputEntry id="inputEntry1">

<text>

<!--生成的表達式爲personName.equals('Angus')  -->

<![CDATA[

.equals('Angus') 

]]>

</text>

</inputEntry>

</rule>

<rule>

<inputEntry id="inputEntry2">

<text>

<!--生成的表達式爲 personName == 'Angus'  -->

<![CDATA[

== 'Angus' 

]]>

</text>

</inputEntry>

</rule>

代碼清單15-15中定義了兩個規則,第一個規則定義的MVEL表達式爲“.equals”,此種情況下,Activiti會自動生成“personName.equals”這樣的語句,personName是輸入參數的名稱。第二個規則定義的表達式爲“==Angus”,則Activiti會自動生成“personName == Angus”,即自動加上參數名稱與一個空格。對比這兩種情況可知,Activiti會根據我們定義的表達式是否以“.”(點)開頭,然後分別作兩種處理。在寫規則的MVEL表達式時,要注意這個細節。

 本文節選自《瘋狂Workflow講義(第2版)》

京東購買地址:https://item.jd.com/12246565.html

工作流Activiti6電子書http://blog.csdn.net/boxiong86/article/details/78488226

工作流Activiti6教學視頻http://blog.csdn.net/boxiong86/article/details/78608585

發佈了66 篇原創文章 · 獲贊 10 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章