JBoss规则引擎与Web Services <o:p></o:p>
作者: Mark Proctor <o:p></o:p>
我最近刚刚完成了一个项目,其中JBoss规则引擎通过Web Services来提供使用。因此我写下其中的一些细节。<o:p></o:p>
在这个特殊的项目中,只有有效负载(payload)中的根对象被设置,整个payload不被分成更小的关联对象设置到Working Memory中,通常这样被认为是最佳实践方式;无论怎样,我们在这里演示给你看怎样有效率的在嵌套的XML有效负载中使用‘from’。
我所理解的步骤可以简单定义如下:<o:p></o:p>
- 为你的模型建立一个XSD<o:p></o:p>
- 使用JAXB's XJC产生类<o:p></o:p>
- 在你的XML有效负载中解包(Unmarshal),并设置root对象<o:p></o:p>
- 在你的规则中使用from对模型导航<o:p></o:p>
- 得到修改后的模型和封包(marshal)<o:p></o:p>
为你的模型建立XSD
<o:p></o:p>
一开始你需要使用XSD来描述你的模式,看起来如下:
xml 代码
- <?xml version="1.0" encoding="UTF-8"?>
- <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="creditscore" targetNamespace="creditscore">
- <xs:complexType name="root">
- <xs:sequence>
- <xs:element name="division" type="xs:string"/>
- <xs:element name="occupancy" type="xs:string"/>
- <xs:element name="occupancyAdjustment" type="xs:double"/>
- <xs:element name="creditScore" type="CreditScore" minOccurs="0"/>
- </xs:sequence>
- </xs:complexType>
-
- <xs:complexType name="CreditScore">
- <xs:sequence>
- <xs:element name="programGroup" type="xs:string"/>
- <xs:element name="lienType" type="xs:string"/>
- <xs:element name="division" type="xs:string"/>
- <xs:element name="score" type="xs:double"/>
- </xs:sequence>
- </xs:complexType>
-
- <xs:element name="Root" type="root"/>
- </xs:schema>
Pojo
从Sun网站https://jaxb.dev.java.net/可获得最新的JAXB参考实现,我使用jaxb<st1:chsdate w:st="on" isrocdate="False" year="1899" day="30" islunardate="False" month="12">2.1.3</st1:chsdate>。从命令行执行下面的命令:<o:p></o:p>
jaxb-ri-20070413\bin\xjc -p org.domain -d c:\folder MyModel.xsd <o:p></o:p>
这建立了三个对象,ObjectFactory和Root、CreditScore两个类。看起来如下:<o:p></o:p>
<o:p> </o:p>
<o:p>
java 代码
- @XmlAccessorType(XmlAccessType.FIELD)
- @XmlType(name = "root", propOrder = {"division", "occupancy", "occupancyAdjustment", "creditScore1", "creditScore2"})
- public class Root {
- @XmlElement(required = true)
- protected String division;
- @XmlElement(required = true)
- protected String occupancy;
- protected double occupancyAdjustment;
- protected CreditScore creditScore1;
- protected List creditScore2;
-
- public String getDivision() {
- return division;
- }
-
- public void setDivision(String value) {
- this.division = value;
- }
-
- public String getOccupancy() {
- return occupancy;
- }
-
- public void setOccupancy(String value) {
- this.occupancy = value;
- }
-
- public double getOccupancyAdjustment() {
- return occupancyAdjustment;
- }
-
- public void setOccupancyAdjustment(double value) {
- this.occupancyAdjustment = value;
- }
-
- public CreditScore getCreditScore1() {
- return creditScore1;
- }
-
- public void setCreditScore1(CreditScore value) {
- this.creditScore1 = value;
- }
-
- public List getCreditScore2() {
- if ( creditScore2 == null ) {
- creditScore2 = new ArrayList();
- }
- return this.creditScore2;
- }
- }
-
- @XmlAccessorType(XmlAccessType.FIELD)
- @XmlType(name = "CreditScore", propOrder = {"programGroup", "lienType", "division", "score"})
- public class CreditScore {
-
- @XmlElement(required = true)
- protected String programGroup;
- @XmlElement(required = true)
- protected String lienType;
- @XmlElement(required = true)
- protected String division;
- protected double score;
-
- public String getProgramGroup() {
- return programGroup;
- }
-
- public void setProgramGroup(String value) {
- this.programGroup = value;
- }
-
- public String getLienType() {
- return lienType;
- }
-
- public void setLienType(String value) {
- this.lienType = value;
- }
-
- public String getDivision() {
- return division;
- }
-
- public void setDivision(String value) {
- this.division = value;
- }
-
- public double getScore() {
- return score;
- }
-
- public void setScore(double value) {
- this.score = value;
- }
- }
-
在你的XML有效负载中解包(Unmarshal),并设置Root对象
<o:p></o:p>
你现在可以用JAXB解包你的XML负载:<o:p></o:p>
<o:p> </o:p>
<o:p>
java 代码
</o:p><o:p>
- JAXBContextImpl jc = (JAXBContextImpl) JAXBContext.newInstance( "org.domain" );
- Unmarshaller unmarshaller = jc.createUnmarshaller();
- JAXBElement element = ( JAXBElement ) unmarshaller.unmarshal( new File( XML_FILE ) );
- Root root = ( Root ) element.getValue();
在你的规则中使用from对模型导航<o:p></o:p>
'from' 在Drools4.0中是一个新的元素,它允许规则对working memory以外的数据上进行规则推论。我们可以使用‘from’对模型中的子对象进行导航<o:p></o:p>
<o:p> </o:p>
<o:p></o:p>得到修改后的模型和封包(marshal)<o:p></o:p>
java 代码
- package creditscore
-
- import creditscore.CreditScore
-
- rule "Credit_Score_Adjustments_0"
- dialect "mvel"
- no-loop true
- when
- r : Root( division=="wholesale",
- occupancy=="Investors" )
- cs : CreditScore( programGroup=="ACMEPowerBuyerGroup",
- lienType=="FIRST_TD; SECOND_TD",
- division=="Wholesale",
- score >= 500,
- score <= 579) from r.creditscore
- then
- cs.score = cs.score + 1;
- modify(cs);
- end
<o:p> </o:p>
<o:p>
java 代码
</o:p><o:p>
- RuleBase ruleBase = RuleBaseFactory.newRuleBase();
- ruleBase.addPackage( pkg );
-
- StatelessSession session = ruleBase.newStatelessSession();
-
- StatelessSessionResult results = session.executeWithResults( new Object[] { root } );
-
- Root returnedRoot = ( Root ) results.iterateObjects().next();
- Marshaller marshaller = jc.createMarshaller();
- marshaller.marshal( new JAXBElement( new QName("org.domain", "Root"), returnedRoot.getClass(), returnedRoot ), System.out );
</o:p></o:p></o:p>模型现在可以使用JAXB's XJC建立。